⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 execution_monitor.ipp

📁 C++的一个好库。。。现在很流行
💻 IPP
📖 第 1 页 / 共 2 页
字号:
signal_handler* signal_handler::s_active_handler = NULL; //!! need to be placed in thread specific storage

//____________________________________________________________________________//

extern "C" {

static void execution_monitor_signal_handler( int sig )
{
    siglongjmp( signal_handler::jump_buffer(), sig );
}

}

//____________________________________________________________________________//

signal_handler::signal_handler( bool catch_system_errors, int timeout )
: m_prev_handler( s_active_handler )
, m_catch_system_errors( catch_system_errors )
, m_set_timeout( timeout > 0 )
{
    s_active_handler = this;

    if( m_catch_system_errors || m_set_timeout ) {
        m_same_action_for_all_signals.sa_flags   = 0;
        m_same_action_for_all_signals.sa_handler = &execution_monitor_signal_handler;
        sigemptyset( &m_same_action_for_all_signals.sa_mask );
    }

    if( m_catch_system_errors ) {
        sigaction( SIGFPE , &m_same_action_for_all_signals, &m_old_SIGFPE_action  );
        sigaction( SIGTRAP, &m_same_action_for_all_signals, &m_old_SIGTRAP_action );
        sigaction( SIGSEGV, &m_same_action_for_all_signals, &m_old_SIGSEGV_action );
        sigaction( SIGBUS , &m_same_action_for_all_signals, &m_old_SIGBUS_action  );
        sigaction( SIGABRT, &m_same_action_for_all_signals, &m_old_SIGABRT_action  );
    }

    if( m_set_timeout ) {
        sigaction( SIGALRM , &m_same_action_for_all_signals, &m_old_SIGALRM_action );
        alarm( timeout );
    }
}

//____________________________________________________________________________//

signal_handler::~signal_handler()
{
    typedef struct sigaction* sigaction_ptr;

    assert( s_active_handler == this );

    if( m_set_timeout ) {
        alarm( 0 );
        sigaction( SIGALRM, &m_old_SIGALRM_action, sigaction_ptr() );
    }

    if( m_catch_system_errors ) {
        sigaction( SIGFPE , &m_old_SIGFPE_action , sigaction_ptr() );
        sigaction( SIGTRAP, &m_old_SIGTRAP_action, sigaction_ptr() );
        sigaction( SIGSEGV, &m_old_SIGSEGV_action, sigaction_ptr() );
        sigaction( SIGBUS , &m_old_SIGBUS_action , sigaction_ptr() );
        sigaction( SIGABRT, &m_old_SIGABRT_action, sigaction_ptr() );
    }

    s_active_handler = m_prev_handler;
}

//____________________________________________________________________________//

} // namespace detail

// ************************************************************************** //
// **************        execution_monitor::catch_signals      ************** //
// ************************************************************************** //

int
execution_monitor::catch_signals( unit_test::callback0<int> const& F, bool catch_system_errors, int timeout )
{
    using namespace detail;
    typedef execution_exception::error_code ec_type;

    signal_handler local_signal_handler( catch_system_errors, timeout );
    int            result = 0;
    ec_type        ec     = execution_exception::no_error;
    const_string   em;

    volatile int   sigtype = sigsetjmp( signal_handler::jump_buffer(), 1 );
    if( sigtype == 0 ) {
        result = m_custom_translators ? (*m_custom_translators)( F ) : F();
    }
    else {
        switch(sigtype) {
        case SIGALRM:
            ec = execution_exception::timeout_error;
            em = BOOST_TEST_L( "signal: SIGALRM (timeout while executing function)" );
            break;
        case SIGTRAP:
            ec = execution_exception::system_error;
            em = BOOST_TEST_L( "signal: SIGTRAP (perhaps integer divide by zero)" );
            break;
        case SIGFPE:
            ec = execution_exception::system_error;
            em = BOOST_TEST_L( "signal: SIGFPE (arithmetic exception)" );
            break;
        case SIGABRT:
            ec = execution_exception::system_error;
            em = BOOST_TEST_L( "signal: SIGABRT (application abort requested)" );
            break;
        case SIGSEGV:
        case SIGBUS:
            ec = execution_exception::system_fatal_error;
            em = BOOST_TEST_L( "signal: memory access violation" );
            break;
        default:
            ec = execution_exception::system_error;
            em = BOOST_TEST_L( "signal: unrecognized signal" );
        }
    }

    if( ec != execution_exception::no_error )
        throw unix_signal_exception( ec, em );

    return result;
}  // unix catch_signals

//____________________________________________________________________________//

#elif (defined(__BORLANDC__) && defined(_Windows) && !defined(BOOST_DISABLE_WIN32))

// this works for Borland but not other Win32 compilers (which trap too many cases)
int
execution_monitor::catch_signals( unit_test::callback0<int> const& F, bool catch_system_errors, int )
{
    int result;

    if( catch_system_errors ) {
        __try { result = m_custom_translators ? (*m_custom_translators)( F ) : F(); }

        __except (1) {
            throw detail::ms_se_exception( GetExceptionCode() );
        }
    }
    else
        result = m_custom_translators ? (*m_custom_translators)( F ) : F();

    return result;
}

#else  // default signal handler

int
execution_monitor::catch_signals( unit_test::callback0<int> const& F, bool, int )
{
    return m_custom_translators ? (*m_custom_translators)( F ) : F();
}

#endif  // choose signal handler

// ************************************************************************** //
// **************   Microsoft structured exception handling    ************** //
// ************************************************************************** //

#if defined(BOOST_MS_STRUCTURED_EXCEPTION_HANDLING)

namespace detail {

void BOOST_TEST_CALL_DECL
ms_se_trans_func( unsigned int id, _EXCEPTION_POINTERS* /* exps */ )
{
    throw ms_se_exception( id );
}

//____________________________________________________________________________//

void BOOST_TEST_CALL_DECL 
ms_se_forward_func( unsigned int /* id */, _EXCEPTION_POINTERS* /* exps */ )
{
    throw;
}

//____________________________________________________________________________//

void
report_ms_se_error( unsigned int id )
{
    switch( id ) {
        // cases classified as fatal_system_error
    case EXCEPTION_ACCESS_VIOLATION:
        detail::report_error( execution_exception::system_fatal_error, "memory access violation" );
        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, "privileged instruction" );
        break;

    case EXCEPTION_IN_PAGE_ERROR:
        detail::report_error( execution_exception::system_fatal_error, "memory page error" );
        break;

    case EXCEPTION_STACK_OVERFLOW:
        detail::report_error( execution_exception::system_fatal_error, "stack overflow" );
        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, "floating point stack check" );
        break;

    case EXCEPTION_FLT_DENORMAL_OPERAND:
    case EXCEPTION_FLT_INEXACT_RESULT:
    case EXCEPTION_FLT_INVALID_OPERATION:
    case EXCEPTION_FLT_OVERFLOW:
    case EXCEPTION_FLT_UNDERFLOW:
        detail::report_error( execution_exception::system_error, "floating point error" );
        break;

    default:
        detail::report_error( execution_exception::system_error, "unrecognized exception or signal" );
        break;
    }  // switch
}  // report_ms_se_error

//____________________________________________________________________________//

} // namespace detail

#endif  // Microsoft structured exception handling

// ************************************************************************** //
// **************                  report_error                ************** //
// ************************************************************************** //

namespace detail {

static void report_error( execution_exception::error_code ec, const_string msg1, const_string msg2 )
{
    static char buf[REPORT_ERROR_BUFFER_SIZE];

    buf[0] = '\0';

    std::strncat( buf, msg1.begin(), sizeof(buf)-1 );
    std::strncat( buf, msg2.begin(), sizeof(buf) - msg1.size() - 1 );

    throw execution_exception( ec, buf );
}

//____________________________________________________________________________//

} // namespace detail

// ************************************************************************** //
// **************             detect_memory_leak              ************** //
// ************************************************************************** //

void
detect_memory_leak( long mem_leak_alloc_num )
{
    unit_test::ut_detail::ignore_unused_variable_warning( mem_leak_alloc_num );

#ifdef BOOST_MS_CRT_DEBUG_HOOKS
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
    
    if( mem_leak_alloc_num > 1 )
        _CrtSetBreakAlloc( mem_leak_alloc_num );
#endif // BOOST_MS_CRT_DEBUG_HOOKS
}

} // namespace boost

//____________________________________________________________________________//

#include <boost/test/detail/enable_warnings.hpp>

// ***************************************************************************
//  Revision History :
//
//  $Log: execution_monitor.ipp,v $
//  Revision 1.9  2005/04/30 17:07:22  rogeeff
//  ignore_warning included
//
//  Revision 1.8  2005/04/30 16:46:50  rogeeff
//  warning suppressed
//
//  Revision 1.7  2005/04/13 05:32:03  rogeeff
//  typo fix
//
//  Revision 1.6  2005/04/05 06:11:37  rogeeff
//  memory leak allocation point detection\nextra help with _WIN32_WINNT
//
//  Revision 1.5  2005/02/20 08:27:07  rogeeff
//  This a major update for Boost.Test framework. See release docs for complete list of fixes/updates
//
//  Revision 1.4  2005/02/01 06:40:07  rogeeff
//  copyright update
//  old log entries removed
//  minor stilistic changes
//  depricated tools removed
//
//  Revision 1.3  2005/01/31 07:50:06  rogeeff
//  cdecl portability fix
//
//  Revision 1.2  2005/01/31 05:58:03  rogeeff
//  detect_memory_leak feature added
//
//  Revision 1.1  2005/01/22 19:22:12  rogeeff
//  implementation moved into headers section to eliminate dependency of included/minimal component on src directory
//
//  Revision 1.36  2005/01/21 07:21:38  rogeeff
//  detect presence of debugger under VC and automatically prevent catching system errors
//
// ***************************************************************************

#endif // BOOST_TEST_EXECUTION_MONITOR_IPP_012205GER

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -