execution_monitor.ipp
字号:
{} void report() const; int operator()( unsigned int id, _EXCEPTION_POINTERS* exps );private: // Data members execution_monitor* m_em; unsigned int m_se_id; void* m_fault_address; bool m_dir;};static voidseh_catch_preventer( unsigned int /* id */, _EXCEPTION_POINTERS* /* exps */ ){ throw;}//____________________________________________________________________________//intsystem_signal_exception::operator()( unsigned int id, _EXCEPTION_POINTERS* exps ){ const unsigned int MSFT_CPP_EXCEPT = 0xE06d7363; // EMSC if( !m_em->p_catch_system_errors || (id == MSFT_CPP_EXCEPT) ) return EXCEPTION_CONTINUE_SEARCH; if( !!m_em->p_auto_start_dbg && debug::attach_debugger( false ) ) { m_em->p_catch_system_errors.value = false; _set_se_translator( &seh_catch_preventer ); return EXCEPTION_CONTINUE_EXECUTION; } m_se_id = id; if( m_se_id == EXCEPTION_ACCESS_VIOLATION && exps->ExceptionRecord->NumberParameters == 2 ) { m_fault_address = (void*)exps->ExceptionRecord->ExceptionInformation[1]; m_dir = exps->ExceptionRecord->ExceptionInformation[0] == 0; } return EXCEPTION_EXECUTE_HANDLER;}//____________________________________________________________________________//voidsystem_signal_exception::report() const{ switch( m_se_id ) { // cases classified as system_fatal_error case EXCEPTION_ACCESS_VIOLATION: { if( !m_fault_address ) detail::report_error( execution_exception::system_fatal_error, "memory access violation" ); else detail::report_error( execution_exception::system_fatal_error, "memory access violation occurred at address 0x%08lx, while attempting to %s", m_fault_address, m_dir ? " read inaccessible data" : " write to an inaccessible (or protected) address" ); break; } case EXCEPTION_ILLEGAL_INSTRUCTION: detail::report_error( execution_exception::system_fatal_error, "illegal instruction" ); break; case EXCEPTION_PRIV_INSTRUCTION: detail::report_error( execution_exception::system_fatal_error, "tried to execute an instruction whose operation is not allowed in the current machine mode" ); break; case EXCEPTION_IN_PAGE_ERROR: detail::report_error( execution_exception::system_fatal_error, "access to a memory page that is not present" ); break; case EXCEPTION_STACK_OVERFLOW: detail::report_error( execution_exception::system_fatal_error, "stack overflow" ); break; case EXCEPTION_NONCONTINUABLE_EXCEPTION: detail::report_error( execution_exception::system_fatal_error, "tried to continue execution after a non continuable exception occurred" ); break; // cases classified as (non-fatal) system_trap case EXCEPTION_DATATYPE_MISALIGNMENT: detail::report_error( execution_exception::system_error, "data misalignment" ); break; case EXCEPTION_INT_DIVIDE_BY_ZERO: detail::report_error( execution_exception::system_error, "integer divide by zero" ); break; case EXCEPTION_INT_OVERFLOW: detail::report_error( execution_exception::system_error, "integer overflow" ); break; case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: detail::report_error( execution_exception::system_error, "array bounds exceeded" ); break; case EXCEPTION_FLT_DIVIDE_BY_ZERO: detail::report_error( execution_exception::system_error, "floating point divide by zero" ); break; case EXCEPTION_FLT_STACK_CHECK: detail::report_error( execution_exception::system_error, "stack overflowed or underflowed as the result of a floating-point operation" ); break; case EXCEPTION_FLT_DENORMAL_OPERAND: detail::report_error( execution_exception::system_error, "operand of floating point operation is denormal" ); break;# if 0 // !! ?? case EXCEPTION_FLT_INEXACT_RESULT: detail::report_error( execution_exception::system_error, "result of a floating-point operation cannot be represented exactly" ); break;#endif case EXCEPTION_FLT_OVERFLOW: detail::report_error( execution_exception::system_error, "exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type" ); break; case EXCEPTION_FLT_UNDERFLOW: detail::report_error( execution_exception::system_error, "exponent of a floating-point operation is less than the magnitude allowed by the corresponding type" ); break; case EXCEPTION_FLT_INVALID_OPERATION: detail::report_error( execution_exception::system_error, "floating point error" ); break; case EXCEPTION_BREAKPOINT: detail::report_error( execution_exception::system_error, "breakpoint encountered" ); break; default: detail::report_error( execution_exception::system_error, "unrecognized exception. Id: 0x%08lx", m_se_id ); break; }}//____________________________________________________________________________//#if defined(BOOST_TEST_USE_DEBUG_MS_CRT)// ************************************************************************** //// ************** assert_reporting_function ************** //// ************************************************************************** //int BOOST_TEST_CALL_DECLassert_reporting_function( int reportType, char* userMessage, int* retVal ){ switch( reportType ) { case _CRT_ASSERT: detail::report_error( execution_exception::user_error, userMessage ); return 1; // return value and retVal are not important since we never reach this line case _CRT_ERROR: detail::report_error( execution_exception::system_error, userMessage ); return 1; // return value and retVal are not important since we never reach this line default: return 0; // use usual reporting method }} // assert_reporting_function#endif//____________________________________________________________________________//void BOOST_TEST_CALL_DECLinvalid_param_handler( wchar_t const* /* expr */, wchar_t const* /* func */, wchar_t const* /* file */, unsigned int /* line */, uintptr_t /* reserved */){ detail::report_error( execution_exception::user_error, "Invalid parameter detected by C runtime library" );}//____________________________________________________________________________//void BOOST_TEST_CALL_DECLswitch_fp_exceptions( bool on_off ){ if( !on_off ) _clearfp(); int cw = ::_controlfp( 0, 0 ); int exceptions_mask = EM_INVALID|EM_DENORMAL|EM_ZERODIVIDE|EM_OVERFLOW|EM_UNDERFLOW; if( on_off ) cw &= ~exceptions_mask; // Set the exception masks on, turn exceptions off else cw |= exceptions_mask; // Set the exception masks off, turn exceptions on if( on_off ) _clearfp(); // Set the control word ::_controlfp( cw, MCW_EM );}//____________________________________________________________________________//} // namespace detail// ************************************************************************** //// ************** execution_monitor::catch_signals ************** //// ************************************************************************** //intexecution_monitor::catch_signals( unit_test::callback0<int> const& F ){ _invalid_parameter_handler old_iph = _invalid_parameter_handler(); if( !p_catch_system_errors ) _set_se_translator( &detail::seh_catch_preventer ); else { if( !!p_detect_fp_exceptions ) detail::switch_fp_exceptions( true );#ifdef BOOST_TEST_USE_DEBUG_MS_CRT _CrtSetReportHook( &detail::assert_reporting_function );#endif old_iph = _set_invalid_parameter_handler( reinterpret_cast<_invalid_parameter_handler>( &detail::invalid_param_handler ) ); } detail::system_signal_exception SSE( this ); int ret_val = 0; __try { __try { ret_val = detail::do_invoke( m_custom_translators, F ); } __except( SSE( GetExceptionCode(), GetExceptionInformation() ) ) { throw SSE; } } __finally { if( !!p_catch_system_errors ) { if( !!p_detect_fp_exceptions ) detail::switch_fp_exceptions( false ); _set_invalid_parameter_handler( old_iph ); } } return ret_val;}//____________________________________________________________________________//#else // default signal handlernamespace detail {class system_signal_exception {public: void report() const {}};} // namespace detailintexecution_monitor::catch_signals( unit_test::callback0<int> const& F ){ return detail::do_invoke( m_custom_translators , F );}//____________________________________________________________________________//#endif // choose signal handler// ************************************************************************** //// ************** execution_monitor::execute ************** //// ************************************************************************** //intexecution_monitor::execute( unit_test::callback0<int> const& F ){ if( debug::under_debugger() ) p_catch_system_errors.value = false; try { return catch_signals( F ); } // Catch-clause reference arguments are a bit different from function // arguments (ISO 15.3 paragraphs 18 & 19). Apparently const isn't // required. Programmers ask for const anyhow, so we supply it. That's // easier than answering questions about non-const usage. catch( char const* ex ) { detail::report_error( execution_exception::cpp_exception_error, "C string: %s", ex ); } catch( std::string const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::string: %s", ex.c_str() ); } // std:: exceptions catch( std::bad_alloc const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::bad_alloc: %s", ex.what() ); }#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0551) catch( std::bad_cast const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::bad_cast" ); } catch( std::bad_typeid const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::bad_typeid" ); }#else catch( std::bad_cast const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::bad_cast: %s", ex.what() ); } catch( std::bad_typeid const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::bad_typeid: %s", ex.what() ); }#endif catch( std::bad_exception const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::bad_exception: %s", ex.what() ); } catch( std::domain_error const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::domain_error: %s", ex.what() ); } catch( std::invalid_argument const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::invalid_argument: %s", ex.what() ); } catch( std::length_error const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::length_error: %s", ex.what() ); } catch( std::out_of_range const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::out_of_range: %s", ex.what() ); } catch( std::range_error const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::range_error: %s", ex.what() ); } catch( std::overflow_error const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::overflow_error: %s", ex.what() ); } catch( std::underflow_error const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::underflow_error: %s", ex.what() ); } catch( std::logic_error const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::logic_error: %s", ex.what() ); } catch( std::runtime_error const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::runtime_error: %s", ex.what() ); } catch( std::exception const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "std::exception: %s", ex.what() ); } catch( system_error const& ex ) { detail::report_error( execution_exception::cpp_exception_error, "system_error produced by: %s: %s", ex.p_failed_exp.get(), std::strerror( ex.p_errno ) ); } catch( detail::system_signal_exception const& ex ) { ex.report(); } catch( execution_aborted const& ) { return 0; } catch( execution_exception const& ) { throw; } catch( ... ) { detail::report_error( execution_exception::cpp_exception_error, "unknown type" ); } return 0; // never reached; supplied to quiet compiler warnings} // execute//____________________________________________________________________________//// ************************************************************************** //// ************** system_error ************** //// ************************************************************************** //system_error::system_error( char const* exp )#ifdef UNDER_CE: p_errno( GetLastError() )#else: p_errno( errno )#endif, p_failed_exp( exp ){}//____________________________________________________________________________//} // namespace boost//____________________________________________________________________________//#include <boost/test/detail/enable_warnings.hpp>#endif // BOOST_TEST_EXECUTION_MONITOR_IPP_012205GER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -