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

📄 execution_monitor.cpp

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 CPP
📖 第 1 页 / 共 2 页
字号:

        return s_active_handler->m_sigjmp_buf;
    }

private:
    // Data members
    struct sigaction        m_same_action_for_all_signals;
    struct sigaction        m_old_SIGFPE_action;
    struct sigaction        m_old_SIGTRAP_action;
    struct sigaction        m_old_SIGSEGV_action;
    struct sigaction        m_old_SIGBUS_action;
    struct sigaction        m_old_SIGABRT_action;
    struct sigaction        m_old_SIGALRM_action;

    sigjmp_buf              m_sigjmp_buf;

    signal_handler*         m_prev_handler;
    static signal_handler*  s_active_handler;

    bool                    m_catch_system_errors;
    bool                    m_set_timeout;
};

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;
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************          boost::detail::catch_signals        ************** //
// ************************************************************************** //

int catch_signals( execution_monitor & exmon, bool catch_system_errors, int timeout )
{
    signal_handler                  local_signal_handler( catch_system_errors, timeout );
    int                             result = 0;
    execution_exception::error_code ec     = execution_exception::no_error;
    c_string_literal                em     = c_string_literal();

    volatile int sigtype = sigsetjmp( signal_handler::jump_buffer(), 1 );
    if( sigtype == 0 ) {
        result = exmon.run_function();
    }
    else {
        switch(sigtype) {
        case SIGALRM:
            ec = execution_exception::timeout_error;
            em = "signal: SIGALRM (timeout while executing function)";
            break;
        case SIGTRAP:
            ec = execution_exception::system_error;
            em = "signal: SIGTRAP (perhaps integer divide by zero)";
            break;
        case SIGFPE:
            ec = execution_exception::system_error;
            em = "signal: SIGFPE (arithmetic exception)";
            break;
        case SIGABRT:
            ec = execution_exception::system_error;
            em = "signal: SIGABRT (application abort requested)";
            break;
        case SIGSEGV:
        case SIGBUS:
            ec = execution_exception::system_fatal_error;
            em = "signal: memory access violation";
            break;
        default:
            ec = execution_exception::system_error;
            em = "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 catch_signals( execution_monitor & exmon, bool catch_system_errors, int )
{
    int result;

    if( catch_system_errors ) {
        __try { result = exmon.run_function(); }

        __except (1)
        {
            throw ms_se_exception( GetExceptionCode() );
        }
    }
    else {
        result = exmon.run_function();
    }
    return result;
}

#else  // default signal handler

int catch_signals( execution_monitor& exmon, bool, int )
{
    return exmon.run_function();
}

#endif  // choose signal handler

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

#if defined(BOOST_MS_STRCTURED_EXCEPTION_HANDLING)

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

//____________________________________________________________________________//

void
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

//____________________________________________________________________________//

#endif  // Microsoft structured exception handling

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

static void report_error( execution_exception::error_code ec, c_string_literal msg1, c_string_literal msg2 )
{
    static char buf[REPORT_ERROR_BUFFER_SIZE];
    buf[0] = '\0';
    std::strncat( buf, msg1, sizeof(buf)-1 );
    std::strncat( buf, msg2, sizeof(buf)-1-std::strlen(buf) );
    throw execution_exception( ec, buf );
}

//____________________________________________________________________________//

} // namespace detail

} // namespace boost

// ***************************************************************************
//  Revision History :
//
//  $Log: execution_monitor.cpp,v $
//  Revision 1.30  2003/12/20 11:27:28  johnmaddock
//  Added fixes for Borland C++ 6.0 compiler (With EDG frontend).
//
//  Revision 1.29  2003/12/01 00:42:37  rogeeff
//  prerelease cleaning
//

// ***************************************************************************

// EOF

⌨️ 快捷键说明

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