// (C) Copyright Gennadiy Rozental 2001-2005. // (C) Copyright Beman Dawes 2001. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/test for the library home page. // // File : $RCSfile: execution_monitor.hpp,v $ // // Version : $Revision: 1.23 $ // // Description : defines abstract monitor interfaces and implements execution exception // The original Boost Test Library included an implementation detail function // named catch_exceptions() which caught otherwise uncaught C++ exceptions. // It was derived from an existing test framework by Beman Dawes. The // intent was to expand later to catch other detectable but platform dependent // error events like Unix signals or Windows structured C exceptions. // // Requests from early adopters of the Boost Test Library included // configurable levels of error message detail, elimination of templates, // separation of error reporting, and making the catch_exceptions() facilities // available as a public interface. Support for unit testing also stretched // the function based design. Implementation within the header became less // attractive due to the need to include many huge system dependent headers, // although still preferable in certain cases. // // All those issues have been addressed by introducing the class-based // design presented here. // *************************************************************************** #ifndef BOOST_TEST_EXECUTION_MONITOR_HPP_071894GER #define BOOST_TEST_EXECUTION_MONITOR_HPP_071894GER // Boost.Test #include #include #include // Boost #include #include #include #include //____________________________________________________________________________// namespace boost { namespace detail { // ************************************************************************** // // ************** detail::translate_exception_base ************** // // ************************************************************************** // class translate_exception_base { public: // Constructor explicit translate_exception_base( boost::scoped_ptr& next ) { next.swap( m_next ); } // Destructor virtual ~translate_exception_base() {} virtual int operator()( unit_test::callback0 const& F ) = 0; protected: // Data members boost::scoped_ptr m_next; }; } // namespace detail // ************************************************************************** // // ************** execution_exception ************** // // ************************************************************************** // // design rationale: fear of being out (or nearly out) of memory. class execution_exception { typedef boost::unit_test::const_string const_string; public: enum error_code { // These values are sometimes used as program return codes. // The particular values have been chosen to avoid conflicts with // commonly used program return codes: values < 100 are often user // assigned, values > 255 are sometimes used to report system errors. // Gaps in values allow for orderly expansion. no_error = 0, // for completeness only; never returned user_error = 200, // user reported non-fatal error cpp_exception_error = 205, // see note (1) below system_error = 210, // see note (2) below timeout_error = 215, // only detectable on certain platforms user_fatal_error = 220, // user reported fatal error system_fatal_error = 225 // see note (2) below // Note 1: Only uncaught C++ exceptions are treated as errors. // If the application catches a C++ exception, it will never reach // the execution_monitor. // Note 2: These errors include Unix signals and Windows structured // exceptions. They are often initiated by hardware traps. // // The implementation decides what is a fatal_system_exception and what is // just a system_exception. Fatal errors are so likely to have corrupted // machine state (like a stack overflow or addressing exception) that it // is unreasonable to continue execution. }; // Constructor execution_exception( error_code ec_, const_string what_msg_ ) // max length 256 inc '\0' : m_error_code( ec_ ), m_what( what_msg_ ) {} // access methods error_code code() const { return m_error_code; } const_string what() const { return m_what; } private: // Data members error_code m_error_code; const_string m_what; }; // execution_exception // ************************************************************************** // // ************** execution_monitor ************** // // ************************************************************************** // class execution_monitor { public: int execute( unit_test::callback0 const& F, bool catch_system_errors = true, int timeout = 0 ); // The catch_system_errors parameter specifies whether the monitor should // try to catch system errors/exceptions that would cause program to crash // in regular case // The timeout argument specifies the seconds that elapse before // a timer_error occurs. May be ignored on some platforms. // // Returns: Value returned by function(). // // Effects: Calls executes supplied function F inside a try/catch block which also may // include other unspecified platform dependent error detection code. // // Throws: execution_exception on an uncaught C++ exception, // a hardware or software signal, trap, or other exception. // // Note: execute() doesn't consider it an error for F to return a non-zero value. // register custom (user supplied) exception translator template void register_exception_translator( ExceptionTranslator const& tr, boost::type* = 0 ); private: // implementation helpers int catch_signals( unit_test::callback0 const& F, bool catch_system_errors, int timeout ); // Data members boost::scoped_ptr m_custom_translators; }; // execution_monitor namespace detail { // ************************************************************************** // // ************** detail::translate_exception ************** // // ************************************************************************** // template class translate_exception : public translate_exception_base { typedef boost::scoped_ptr base_ptr; public: explicit translate_exception( ExceptionTranslator const& tr, base_ptr& next ) : translate_exception_base( next ), m_translator( tr ) {} int operator()( unit_test::callback0 const& F ) { try { return m_next ? (*m_next)( F ) : F(); } catch( Exception const& e ) { m_translator( e ); return boost::exit_exception_failure; } } private: // Data members ExceptionTranslator m_translator; }; } // namespace detail template void execution_monitor::register_exception_translator( ExceptionTranslator const& tr, boost::type* ) { m_custom_translators.reset( new detail::translate_exception( tr,m_custom_translators ) ); } // ************************************************************************** // // ************** detect_memory_leak ************** // // ************************************************************************** // // turn on system memory leak detection void detect_memory_leak( long mem_leak_alloc_num = 0 ); // ************************************************************************** // // ************** execution_aborted ************** // // ************************************************************************** // struct execution_aborted {}; } // namespace boost //____________________________________________________________________________// #include // *************************************************************************** // Revision History : // // $Log: execution_monitor.hpp,v $ // Revision 1.23 2005/04/05 06:11:37 rogeeff // memory leak allocation point detection\nextra help with _WIN32_WINNT // // Revision 1.22 2005/02/20 08:27:05 rogeeff // This a major update for Boost.Test framework. See release docs for complete list of fixes/updates // // Revision 1.21 2005/02/01 08:59:28 rogeeff // supplied_log_formatters split // change formatters interface to simplify result interface // // Revision 1.20 2005/02/01 06:40:06 rogeeff // copyright update // old log entries removed // minor stilistic changes // depricated tools removed // // Revision 1.19 2005/01/31 05:59:18 rogeeff // detect_memory_leak feature added // // *************************************************************************** #endif