Home | History | Annotate | Download | only in impl
      1 //  (C) Copyright Gennadiy Rozental 2001-2008.
      2 //  (C) Copyright Beman Dawes and Ullrich Koethe 1995-2001.
      3 //  Use, modification, and distribution are subject to the
      4 //  Boost Software License, Version 1.0. (See accompanying file
      5 //  http://www.boost.org/LICENSE_1_0.txt)
      6 
      7 //  See http://www.boost.org/libs/test for the library home page.
      8 //
      9 //  File        : $RCSfile$
     10 //
     11 //  Version     : $Revision: 57992 $
     12 //
     13 //  Description : provides execution monitor implementation for all supported
     14 //  configurations, including Microsoft structured exception based, unix signals
     15 //  based and special workarounds for borland
     16 //
     17 //  Note that when testing requirements or user wishes preclude use of this
     18 //  file as a separate compilation unit, it may be included as a header file.
     19 //
     20 //  Header dependencies are deliberately restricted to reduce coupling to other
     21 //  boost libraries.
     22 // ***************************************************************************
     23 
     24 #ifndef BOOST_TEST_EXECUTION_MONITOR_IPP_012205GER
     25 #define BOOST_TEST_EXECUTION_MONITOR_IPP_012205GER
     26 
     27 // Boost.Test
     28 #include <boost/test/detail/config.hpp>
     29 #include <boost/test/detail/workaround.hpp>
     30 #include <boost/test/execution_monitor.hpp>
     31 #include <boost/test/debug.hpp>
     32 
     33 // Boost
     34 #include <boost/cstdlib.hpp>    // for exit codes
     35 #include <boost/config.hpp>     // for workarounds
     36 #include <boost/exception/get_error_info.hpp> // for get_error_info
     37 #include <boost/exception/current_exception_cast.hpp> // for current_exception_cast
     38 
     39 // STL
     40 #include <string>               // for std::string
     41 #include <new>                  // for std::bad_alloc
     42 #include <typeinfo>             // for std::bad_cast, std::bad_typeid
     43 #include <exception>            // for std::exception, std::bad_exception
     44 #include <stdexcept>            // for std exception hierarchy
     45 #include <cstring>              // for C string API
     46 #include <cassert>              // for assert
     47 #include <cstddef>              // for NULL
     48 #include <cstdio>               // for vsnprintf
     49 #include <cstdarg>              // for varargs
     50 
     51 #ifdef BOOST_NO_STDC_NAMESPACE
     52 namespace std { using ::strerror; using ::strlen; using ::strncat; }
     53 #endif
     54 
     55 // to use vsnprintf
     56 #if defined(__SUNPRO_CC) || defined(__SunOS)
     57 #  include <stdio.h>
     58 #  include <stdarg.h>
     59 using std::va_list;
     60 #endif
     61 
     62 // to use vsnprintf 
     63 #if defined(__QNXNTO__) 
     64 #  include <stdio.h> 
     65 #endif
     66 
     67 #if defined(_WIN32) && !defined(BOOST_DISABLE_WIN32) &&                  \
     68     (!defined(__COMO__) && !defined(__MWERKS__) && !defined(__GNUC__) || \
     69      BOOST_WORKAROUND(__MWERKS__, >= 0x3000))
     70 
     71 #  define BOOST_SEH_BASED_SIGNAL_HANDLING
     72 
     73 #  include <windows.h>
     74 
     75 #  if defined(__MWERKS__) || (defined(_MSC_VER) && !defined(UNDER_CE))
     76 #    include <eh.h>
     77 #  endif
     78 
     79 #  if defined(__BORLANDC__) && __BORLANDC__ >= 0x560 || defined(__MWERKS__)
     80 #    include <stdint.h>
     81 #  endif
     82 
     83 #  if defined(__BORLANDC__) && __BORLANDC__ < 0x560
     84     typedef unsigned uintptr_t;
     85 #  endif
     86 
     87 #  if BOOST_WORKAROUND(_MSC_VER,  < 1300 ) || defined(UNDER_CE)
     88 typedef void* uintptr_t;
     89 #  endif
     90 
     91 // for the FP control routines
     92 #include <float.h>
     93 
     94 #ifndef EM_INVALID
     95 #define EM_INVALID _EM_INVALID
     96 #endif
     97 
     98 #ifndef EM_DENORMAL
     99 #define EM_DENORMAL _EM_DENORMAL
    100 #endif
    101 
    102 #ifndef EM_ZERODIVIDE
    103 #define EM_ZERODIVIDE _EM_ZERODIVIDE
    104 #endif
    105 
    106 #ifndef EM_OVERFLOW
    107 #define EM_OVERFLOW _EM_OVERFLOW
    108 #endif
    109 
    110 #ifndef EM_UNDERFLOW
    111 #define EM_UNDERFLOW _EM_UNDERFLOW
    112 #endif
    113 
    114 #ifndef MCW_EM
    115 #define MCW_EM _MCW_EM
    116 #endif
    117 
    118 #  if !defined(NDEBUG) && defined(_MSC_VER) && !defined(UNDER_CE)
    119 #    include <crtdbg.h>
    120 #    define BOOST_TEST_CRT_HOOK_TYPE    _CRT_REPORT_HOOK
    121 #    define BOOST_TEST_CRT_ASSERT       _CRT_ASSERT
    122 #    define BOOST_TEST_CRT_ERROR        _CRT_ERROR
    123 #    define BOOST_TEST_CRT_SET_HOOK(H)  _CrtSetReportHook(H)
    124 #  else
    125 #    define BOOST_TEST_CRT_HOOK_TYPE    void*
    126 #    define BOOST_TEST_CRT_ASSERT       2
    127 #    define BOOST_TEST_CRT_ERROR        1
    128 #    define BOOST_TEST_CRT_SET_HOOK(H)  (void*)(H)
    129 #  endif
    130 
    131 #  if !BOOST_WORKAROUND(_MSC_VER,  >= 1400 ) || defined(UNDER_CE)
    132 
    133 typedef void* _invalid_parameter_handler;
    134 
    135 inline _invalid_parameter_handler
    136 _set_invalid_parameter_handler( _invalid_parameter_handler arg )
    137 {
    138     return arg;
    139 }
    140 
    141 #  endif
    142 
    143 #  if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564)) || defined(UNDER_CE)
    144 
    145 namespace { void _set_se_translator( void* ) {} }
    146 
    147 #  endif
    148 
    149 #elif defined(BOOST_HAS_SIGACTION)
    150 
    151 #  define BOOST_SIGACTION_BASED_SIGNAL_HANDLING
    152 
    153 #  include <unistd.h>
    154 #  include <signal.h>
    155 #  include <setjmp.h>
    156 
    157 #  if defined(__FreeBSD__)  
    158 
    159 #    ifndef SIGPOLL
    160 #      define SIGPOLL SIGIO
    161 #    endif
    162 
    163 #    if (__FreeBSD_version < 70100)
    164 
    165 #      define ILL_ILLADR 0 // ILL_RESAD_FAULT
    166 #      define ILL_PRVOPC ILL_PRIVIN_FAULT
    167 #      define ILL_ILLOPN 2 // ILL_RESOP_FAULT
    168 #      define ILL_COPROC ILL_FPOP_FAULT
    169 
    170 #      define BOOST_TEST_LIMITED_SIGNAL_DETAILS
    171 #      define BOOST_TEST_IGNORE_SIGCHLD
    172 
    173 #    endif 
    174 #  endif 
    175 
    176 #  if !defined(__CYGWIN__) && !defined(__QNXNTO__)
    177 #   define BOOST_TEST_USE_ALT_STACK
    178 #  endif
    179 
    180 #  if defined(SIGPOLL) && !defined(__CYGWIN__)                              && \
    181       !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))  && \
    182       !defined(__NetBSD__)                                                  && \
    183       !defined(__QNXNTO__)
    184 #    define BOOST_TEST_CATCH_SIGPOLL
    185 #  endif
    186 
    187 #  ifdef BOOST_TEST_USE_ALT_STACK
    188 #    define BOOST_TEST_ALT_STACK_SIZE SIGSTKSZ
    189 #  endif
    190 
    191 #else
    192 
    193 #  define BOOST_NO_SIGNAL_HANDLING
    194 
    195 #endif
    196 
    197 #ifndef UNDER_CE
    198 #include <errno.h>
    199 #endif
    200 
    201 #include <boost/test/detail/suppress_warnings.hpp>
    202 
    203 //____________________________________________________________________________//
    204 
    205 namespace boost {
    206 
    207 // ************************************************************************** //
    208 // **************                  report_error                ************** //
    209 // ************************************************************************** //
    210 
    211 namespace detail {
    212 
    213 #ifdef __BORLANDC__
    214 #  define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) std::vsnprintf( (a1), (a2), (a3), (a4) )
    215 #elif BOOST_WORKAROUND(_MSC_VER, <= 1310) || \
    216       BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3000)) || \
    217       defined(UNDER_CE)
    218 #  define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) _vsnprintf( (a1), (a2), (a3), (a4) )
    219 #else
    220 #  define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) vsnprintf( (a1), (a2), (a3), (a4) )
    221 #endif
    222 
    223 template <typename ErrorInfo>
    224 typename ErrorInfo::value_type
    225 extract( boost::exception const* ex )
    226 {
    227     if( !ex )
    228         return 0;
    229 
    230     typename ErrorInfo::value_type const * val = boost::get_error_info<ErrorInfo>( *ex );
    231 
    232     return val ? *val : 0;
    233 }
    234 
    235 //____________________________________________________________________________//
    236 
    237 static void
    238 report_error( execution_exception::error_code ec, boost::exception const* be, char const* format, va_list* args )
    239 {
    240     static const int REPORT_ERROR_BUFFER_SIZE = 512;
    241     static char buf[REPORT_ERROR_BUFFER_SIZE];
    242 
    243     BOOST_TEST_VSNPRINTF( buf, sizeof(buf)-1, format, *args ); 
    244     buf[sizeof(buf)-1] = 0;
    245 
    246     va_end( *args );
    247 
    248     throw execution_exception( ec, buf, execution_exception::location( extract<throw_file>( be ), 
    249                                                                        extract<throw_line>( be ),
    250                                                                        extract<throw_function>( be ) ) );
    251 }
    252 
    253 //____________________________________________________________________________//
    254 
    255 static void
    256 report_error( execution_exception::error_code ec, char const* format, ... )
    257 {
    258     va_list args;
    259     va_start( args, format );
    260 
    261     report_error( ec, 0, format, &args );
    262 }
    263 
    264 //____________________________________________________________________________//
    265 
    266 static void
    267 report_error( execution_exception::error_code ec, boost::exception const* be, char const* format, ... )
    268 {
    269     va_list args;
    270     va_start( args, format );
    271 
    272     report_error( ec, be, format, &args );
    273 }
    274 
    275 //____________________________________________________________________________//
    276 
    277 template<typename Tr,typename Functor>
    278 inline int
    279 do_invoke( Tr const& tr, Functor const& F )
    280 {
    281     return tr ? (*tr)( F ) : F();
    282 }
    283 
    284 //____________________________________________________________________________//
    285 
    286 } // namespace detail
    287 
    288 #if defined(BOOST_SIGACTION_BASED_SIGNAL_HANDLING)
    289 
    290 // ************************************************************************** //
    291 // **************       Sigaction based signal handling        ************** //
    292 // ************************************************************************** //
    293 
    294 namespace detail {
    295 
    296 // ************************************************************************** //
    297 // **************    boost::detail::system_signal_exception    ************** //
    298 // ************************************************************************** //
    299 
    300 class system_signal_exception {
    301 public:
    302     // Constructor
    303     system_signal_exception()
    304     : m_sig_info( 0 )
    305     , m_context( 0 )
    306     {}
    307 
    308     // Access methods
    309     void        operator()( siginfo_t* i, void* c )
    310     {
    311         m_sig_info  = i;
    312         m_context   = c;
    313     }
    314     void        report() const;
    315 
    316 private:
    317     // Data members
    318     siginfo_t*  m_sig_info; // system signal detailed info
    319     void*       m_context;  // signal context
    320 };
    321 
    322 //____________________________________________________________________________//
    323 
    324 void
    325 system_signal_exception::report() const
    326 {
    327     if( !m_sig_info )
    328         return; // no error actually occur?
    329 
    330     switch( m_sig_info->si_code ) {
    331     case SI_USER:
    332         report_error( execution_exception::system_error,
    333                       "signal: generated by kill() (or family); uid=%d; pid=%d",
    334                       (int)m_sig_info->si_uid, (int)m_sig_info->si_pid );
    335         break;
    336     case SI_QUEUE:
    337         report_error( execution_exception::system_error,
    338                       "signal: sent by sigqueue()" );
    339         break;
    340     case SI_TIMER:
    341         report_error( execution_exception::system_error,
    342                       "signal: the expiration of a timer set by timer_settimer()" );
    343         break;
    344     case SI_ASYNCIO:
    345         report_error( execution_exception::system_error,
    346                       "signal: generated by the completion of an asynchronous I/O request" );
    347         break;
    348     case SI_MESGQ:
    349         report_error( execution_exception::system_error,
    350                       "signal: generated by the the arrival of a message on an empty message queue" );
    351         break;
    352     default:
    353         break;
    354     }
    355 
    356     switch( m_sig_info->si_signo ) {
    357     case SIGILL:
    358         switch( m_sig_info->si_code ) {
    359 #ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
    360         case ILL_ILLOPC:
    361             report_error( execution_exception::system_fatal_error,
    362                           "signal: illegal opcode; address of failing instruction: 0x%08lx",
    363                           m_sig_info->si_addr );
    364             break;
    365         case ILL_ILLTRP:
    366             report_error( execution_exception::system_fatal_error,
    367                           "signal: illegal trap; address of failing instruction: 0x%08lx",
    368                           m_sig_info->si_addr );
    369             break;
    370         case ILL_PRVREG:
    371             report_error( execution_exception::system_fatal_error,
    372                           "signal: privileged register; address of failing instruction: 0x%08lx",
    373                           m_sig_info->si_addr );
    374             break;
    375         case ILL_BADSTK:
    376             report_error( execution_exception::system_fatal_error,
    377                           "signal: internal stack error; address of failing instruction: 0x%08lx",
    378                           m_sig_info->si_addr );
    379             break;
    380 #endif
    381         case ILL_ILLOPN:
    382             report_error( execution_exception::system_fatal_error,
    383                           "signal: illegal operand; address of failing instruction: 0x%08lx",
    384                           m_sig_info->si_addr );
    385             break;
    386         case ILL_ILLADR:
    387             report_error( execution_exception::system_fatal_error,
    388                           "signal: illegal addressing mode; address of failing instruction: 0x%08lx",
    389                           m_sig_info->si_addr );
    390             break;
    391         case ILL_PRVOPC:
    392             report_error( execution_exception::system_fatal_error,
    393                           "signal: privileged opcode; address of failing instruction: 0x%08lx",
    394                           m_sig_info->si_addr );
    395             break;
    396         case ILL_COPROC:
    397             report_error( execution_exception::system_fatal_error,
    398                           "signal: co-processor error; address of failing instruction: 0x%08lx",
    399                           m_sig_info->si_addr );
    400             break;
    401         default: 
    402             report_error( execution_exception::system_fatal_error, 
    403                           "signal: SIGILL, si_code: %d (illegal instruction; address of failing instruction: 0x%08lx)", 
    404                           m_sig_info->si_addr, m_sig_info->si_code ); 
    405             break;
    406         }
    407         break;
    408 
    409     case SIGFPE:
    410         switch( m_sig_info->si_code ) {
    411         case FPE_INTDIV:
    412             report_error( execution_exception::system_error,
    413                           "signal: integer divide by zero; address of failing instruction: 0x%08lx",
    414                           m_sig_info->si_addr );
    415             break;
    416         case FPE_INTOVF:
    417             report_error( execution_exception::system_error,
    418                           "signal: integer overflow; address of failing instruction: 0x%08lx",
    419                           m_sig_info->si_addr );
    420             break;
    421         case FPE_FLTDIV:
    422             report_error( execution_exception::system_error,
    423                           "signal: floating point divide by zero; address of failing instruction: 0x%08lx",
    424                           m_sig_info->si_addr );
    425             break;
    426         case FPE_FLTOVF:
    427             report_error( execution_exception::system_error,
    428                           "signal: floating point overflow; address of failing instruction: 0x%08lx",
    429                           m_sig_info->si_addr );
    430             break;
    431         case FPE_FLTUND:
    432             report_error( execution_exception::system_error,
    433                           "signal: floating point underflow; address of failing instruction: 0x%08lx",
    434                           m_sig_info->si_addr );
    435             break;
    436         case FPE_FLTRES:
    437             report_error( execution_exception::system_error,
    438                           "signal: floating point inexact result; address of failing instruction: 0x%08lx",
    439                           m_sig_info->si_addr );
    440             break;
    441         case FPE_FLTINV:
    442             report_error( execution_exception::system_error,
    443                           "signal: invalid floating point operation; address of failing instruction: 0x%08lx",
    444                           m_sig_info->si_addr );
    445             break;
    446         case FPE_FLTSUB:
    447             report_error( execution_exception::system_error,
    448                           "signal: subscript out of range; address of failing instruction: 0x%08lx",
    449                           m_sig_info->si_addr );
    450             break;
    451         default:
    452             report_error( execution_exception::system_error,
    453                           "signal: SIGFPE, si_code: %d (errnoneous arithmetic operations; address of failing instruction: 0x%08lx)",
    454                           m_sig_info->si_addr, m_sig_info->si_code );
    455             break;
    456         }
    457         break;
    458 
    459     case SIGSEGV:
    460         switch( m_sig_info->si_code ) {
    461 #ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
    462         case SEGV_MAPERR:
    463             report_error( execution_exception::system_fatal_error,
    464                           "memory access violation at address: 0x%08lx: no mapping at fault address",
    465                           m_sig_info->si_addr );
    466             break;
    467         case SEGV_ACCERR:
    468             report_error( execution_exception::system_fatal_error,
    469                           "memory access violation at address: 0x%08lx: invalid permissions",
    470                           m_sig_info->si_addr );
    471             break;
    472 #endif
    473         default:
    474             report_error( execution_exception::system_fatal_error,
    475                           "signal: SIGSEGV, si_code: %d (memory access violation at address: 0x%08lx)",
    476                           m_sig_info->si_addr, m_sig_info->si_code );
    477             break;
    478         }
    479         break;
    480 
    481     case SIGBUS:
    482         switch( m_sig_info->si_code ) {
    483 #ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
    484         case BUS_ADRALN:
    485             report_error( execution_exception::system_fatal_error,
    486                           "memory access violation at address: 0x%08lx: invalid address alignment",
    487                           m_sig_info->si_addr );
    488             break;
    489         case BUS_ADRERR:
    490             report_error( execution_exception::system_fatal_error,
    491                           "memory access violation at address: 0x%08lx: non-existent physical address",
    492                           m_sig_info->si_addr );
    493             break;
    494         case BUS_OBJERR:
    495             report_error( execution_exception::system_fatal_error,
    496                           "memory access violation at address: 0x%08lx: object specific hardware error",
    497                           m_sig_info->si_addr );
    498             break;
    499 #endif
    500         default:
    501             report_error( execution_exception::system_fatal_error,
    502                           "signal: SIGSEGV, si_code: %d (memory access violation at address: 0x%08lx)",
    503                           m_sig_info->si_addr, m_sig_info->si_code );
    504             break;
    505         }
    506         break;
    507 
    508     case SIGCHLD:
    509         switch( m_sig_info->si_code ) {
    510 #ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
    511         case CLD_EXITED:
    512             report_error( execution_exception::system_error,
    513                           "child has exited; pid: %d; uid: %d; exit value: %d",
    514                           (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
    515             break;
    516         case CLD_KILLED:
    517             report_error( execution_exception::system_error,
    518                           "child was killed; pid: %d; uid: %d; exit value: %d",
    519                           (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
    520             break;
    521         case CLD_DUMPED:
    522             report_error( execution_exception::system_error,
    523                           "child terminated abnormally; pid: %d; uid: %d; exit value: %d",
    524                           (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
    525             break;
    526         case CLD_TRAPPED:
    527             report_error( execution_exception::system_error,
    528                           "traced child has trapped; pid: %d; uid: %d; exit value: %d",
    529                           (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
    530             break;
    531         case CLD_STOPPED:
    532             report_error( execution_exception::system_error,
    533                           "child has stopped; pid: %d; uid: %d; exit value: %d",
    534                           (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
    535             break;
    536         case CLD_CONTINUED:
    537             report_error( execution_exception::system_error,
    538                           "stopped child had continued; pid: %d; uid: %d; exit value: %d",
    539                           (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
    540             break;
    541 #endif
    542         default:
    543             report_error( execution_exception::system_error,
    544                           "signal: SIGCHLD, si_code: %d (child process has terminated; pid: %d; uid: %d; exit value: %d)",
    545                           (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status, m_sig_info->si_code );
    546             break;
    547         }
    548         break;
    549 
    550 #if defined(BOOST_TEST_CATCH_SIGPOLL)
    551 
    552     case SIGPOLL:
    553         switch( m_sig_info->si_code ) {
    554 #ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
    555         case POLL_IN:
    556             report_error( execution_exception::system_error,
    557                           "data input available; band event %d",
    558                           (int)m_sig_info->si_band );
    559             break;
    560         case POLL_OUT:
    561             report_error( execution_exception::system_error,
    562                           "output buffers available; band event %d",
    563                           (int)m_sig_info->si_band );
    564             break;
    565         case POLL_MSG:
    566             report_error( execution_exception::system_error,
    567                           "input message available; band event %d",
    568                           (int)m_sig_info->si_band );
    569             break;
    570         case POLL_ERR:
    571             report_error( execution_exception::system_error,
    572                           "i/o error; band event %d",
    573                           (int)m_sig_info->si_band );
    574             break;
    575         case POLL_PRI:
    576             report_error( execution_exception::system_error,
    577                           "high priority input available; band event %d",
    578                           (int)m_sig_info->si_band );
    579             break;
    580 #if defined(POLL_ERR) && defined(POLL_HUP) && (POLL_ERR - POLL_HUP)
    581         case POLL_HUP:
    582             report_error( execution_exception::system_error,
    583                           "device disconnected; band event %d",
    584                           (int)m_sig_info->si_band );
    585             break;
    586 #endif
    587 #endif
    588         default: 
    589             report_error( execution_exception::system_error, 
    590                           "signal: SIGPOLL, si_code: %d (asynchronous I/O event occured; band event %d)", 
    591                           (int)m_sig_info->si_band, m_sig_info->si_code ); 
    592             break; 
    593         }
    594         break;
    595 
    596 #endif
    597 
    598     case SIGABRT:
    599         report_error( execution_exception::system_error,
    600                       "signal: SIGABRT (application abort requested)" );
    601         break;
    602 
    603     case SIGALRM:
    604         report_error( execution_exception::timeout_error,
    605                       "signal: SIGALRM (timeout while executing function)" );
    606         break;
    607 
    608     default:
    609         report_error( execution_exception::system_error, "unrecognized signal" );
    610     }
    611 }
    612 
    613 //____________________________________________________________________________//
    614 
    615 // ************************************************************************** //
    616 // **************         boost::detail::signal_action         ************** //
    617 // ************************************************************************** //
    618 
    619 // Forward declaration
    620 extern "C" {
    621 static void execution_monitor_jumping_signal_handler( int sig, siginfo_t* info, void* context );
    622 static void execution_monitor_attaching_signal_handler( int sig, siginfo_t* info, void* context );
    623 }
    624 
    625 class signal_action {
    626     typedef struct sigaction* sigaction_ptr;
    627 public:
    628     //Constructor
    629     signal_action();
    630     signal_action( int sig, bool install, bool attach_dbg, char* alt_stack );
    631     ~signal_action();
    632 
    633 private:
    634     // Data members
    635     int                 m_sig;
    636     bool                m_installed;
    637     struct sigaction    m_new_action;
    638     struct sigaction    m_old_action;
    639 };
    640 
    641 //____________________________________________________________________________//
    642 
    643 signal_action::signal_action()
    644 : m_installed( false )
    645 {}
    646 
    647 //____________________________________________________________________________//
    648 
    649 signal_action::signal_action( int sig, bool install, bool attach_dbg, char* alt_stack )
    650 : m_sig( sig )
    651 , m_installed( install )
    652 {
    653     if( !install )
    654         return;
    655 
    656     std::memset( &m_new_action, 0, sizeof(struct sigaction) );
    657 
    658     BOOST_TEST_SYS_ASSERT( ::sigaction( m_sig , sigaction_ptr(), &m_new_action ) != -1 );
    659 
    660     if( m_new_action.sa_sigaction || m_new_action.sa_handler ) {
    661         m_installed = false;
    662         return;
    663     }
    664 
    665     m_new_action.sa_flags     |= SA_SIGINFO;
    666     m_new_action.sa_sigaction  = attach_dbg ? &execution_monitor_attaching_signal_handler
    667                                             : &execution_monitor_jumping_signal_handler;
    668     BOOST_TEST_SYS_ASSERT( sigemptyset( &m_new_action.sa_mask ) != -1 );
    669 
    670 #ifdef BOOST_TEST_USE_ALT_STACK
    671     if( alt_stack )
    672         m_new_action.sa_flags |= SA_ONSTACK;
    673 #endif
    674 
    675     BOOST_TEST_SYS_ASSERT( ::sigaction( m_sig, &m_new_action, &m_old_action ) != -1 );
    676 }
    677 
    678 //____________________________________________________________________________//
    679 
    680 signal_action::~signal_action()
    681 {
    682     if( m_installed )
    683         ::sigaction( m_sig, &m_old_action , sigaction_ptr() );
    684 }
    685 
    686 //____________________________________________________________________________//
    687 
    688 // ************************************************************************** //
    689 // **************        boost::detail::signal_handler         ************** //
    690 // ************************************************************************** //
    691 
    692 class signal_handler {
    693 public:
    694     // Constructor
    695     explicit signal_handler( bool catch_system_errors, int timeout, bool attach_dbg, char* alt_stack );
    696 
    697     // Destructor
    698     ~signal_handler();
    699 
    700     // access methods
    701     static sigjmp_buf&      jump_buffer()
    702     {
    703         assert( !!s_active_handler );
    704 
    705         return s_active_handler->m_sigjmp_buf;
    706     }
    707 
    708     static system_signal_exception&  sys_sig()
    709     {
    710         assert( !!s_active_handler );
    711 
    712         return s_active_handler->m_sys_sig;
    713     }
    714 
    715 private:
    716     // Data members
    717     signal_handler*         m_prev_handler;
    718     int                     m_timeout;
    719 
    720     signal_action           m_ILL_action;
    721     signal_action           m_FPE_action;
    722     signal_action           m_SEGV_action;
    723     signal_action           m_BUS_action;
    724     signal_action           m_CHLD_action;
    725     signal_action           m_POLL_action;
    726     signal_action           m_ABRT_action;
    727     signal_action           m_ALRM_action;
    728 
    729     sigjmp_buf              m_sigjmp_buf;
    730     system_signal_exception m_sys_sig;
    731 
    732     static signal_handler*  s_active_handler;
    733 };
    734 
    735 // !! need to be placed in thread specific storage
    736 typedef signal_handler* signal_handler_ptr;
    737 signal_handler* signal_handler::s_active_handler = signal_handler_ptr();
    738 
    739 //____________________________________________________________________________//
    740 
    741 signal_handler::signal_handler( bool catch_system_errors, int timeout, bool attach_dbg, char* alt_stack )
    742 : m_prev_handler( s_active_handler )
    743 , m_timeout( timeout )
    744 , m_ILL_action ( SIGILL , catch_system_errors, attach_dbg, alt_stack )
    745 , m_FPE_action ( SIGFPE , catch_system_errors, attach_dbg, alt_stack )
    746 , m_SEGV_action( SIGSEGV, catch_system_errors, attach_dbg, alt_stack )
    747 , m_BUS_action ( SIGBUS , catch_system_errors, attach_dbg, alt_stack )
    748 #ifndef BOOST_TEST_IGNORE_SIGCHLD
    749 , m_CHLD_action( SIGCHLD, catch_system_errors, attach_dbg, alt_stack )
    750 #endif
    751 #ifdef BOOST_TEST_CATCH_SIGPOLL
    752 , m_POLL_action( SIGPOLL, catch_system_errors, attach_dbg, alt_stack )
    753 #endif
    754 , m_ABRT_action( SIGABRT, catch_system_errors, attach_dbg, alt_stack )
    755 , m_ALRM_action( SIGALRM, timeout > 0        , attach_dbg, alt_stack )
    756 {
    757     s_active_handler = this;
    758 
    759     if( m_timeout > 0 ) {
    760         ::alarm( 0 );
    761         ::alarm( timeout );
    762     }
    763 
    764 #ifdef BOOST_TEST_USE_ALT_STACK
    765     if( alt_stack ) {
    766         stack_t sigstk;
    767         std::memset( &sigstk, 0, sizeof(stack_t) );
    768 
    769         BOOST_TEST_SYS_ASSERT( ::sigaltstack( 0, &sigstk ) != -1 );
    770 
    771         if( sigstk.ss_flags & SS_DISABLE ) {
    772             sigstk.ss_sp    = alt_stack;
    773             sigstk.ss_size  = BOOST_TEST_ALT_STACK_SIZE;
    774             sigstk.ss_flags = 0;
    775             BOOST_TEST_SYS_ASSERT( ::sigaltstack( &sigstk, 0 ) != -1 );
    776         }
    777     }
    778 #endif
    779 }
    780 
    781 //____________________________________________________________________________//
    782 
    783 signal_handler::~signal_handler()
    784 {
    785     assert( s_active_handler == this );
    786 
    787     if( m_timeout > 0 )
    788         ::alarm( 0 );
    789 
    790 #ifdef BOOST_TEST_USE_ALT_STACK
    791 #ifdef __GNUC__
    792     // We shouldn't need to explicitly initialize all the members here,
    793     // but gcc warns if we don't, so add initializers for each of the
    794     // members specified in the POSIX std:
    795     stack_t sigstk = { 0, 0, 0 };
    796 #else
    797     stack_t sigstk = { };
    798 #endif
    799 
    800     sigstk.ss_size  = MINSIGSTKSZ;
    801     sigstk.ss_flags = SS_DISABLE;
    802     BOOST_TEST_SYS_ASSERT( ::sigaltstack( &sigstk, 0 ) != -1 );
    803 #endif
    804 
    805     s_active_handler = m_prev_handler;
    806 }
    807 
    808 //____________________________________________________________________________//
    809 
    810 // ************************************************************************** //
    811 // **************       execution_monitor_signal_handler       ************** //
    812 // ************************************************************************** //
    813 
    814 extern "C" {
    815 
    816 static bool ignore_sigchild( siginfo_t* info )
    817 {
    818     return info->si_signo == SIGCHLD
    819 #ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
    820             && info->si_code == CLD_EXITED 
    821 #endif
    822 #ifdef BOOST_TEST_IGNORE_NON_ZERO_CHILD_CODE
    823             ;
    824 #else
    825             && (int)info->si_status == 0;
    826 #endif
    827 }
    828 
    829 //____________________________________________________________________________//
    830 
    831 static void execution_monitor_jumping_signal_handler( int sig, siginfo_t* info, void* context )
    832 {
    833     if( ignore_sigchild( info ) )
    834         return;
    835 
    836     signal_handler::sys_sig()( info, context );
    837 
    838     siglongjmp( signal_handler::jump_buffer(), sig );
    839 }
    840 
    841 //____________________________________________________________________________//
    842 
    843 static void execution_monitor_attaching_signal_handler( int sig, siginfo_t* info, void* context )
    844 {
    845     if( ignore_sigchild( info ) )
    846         return;
    847 
    848     if( !debug::attach_debugger( false ) )
    849         execution_monitor_jumping_signal_handler( sig, info, context );
    850 
    851     // debugger attached; it will handle the signal
    852     BOOST_TEST_SYS_ASSERT( ::signal( sig, SIG_DFL ) != SIG_ERR );
    853 }
    854 
    855 //____________________________________________________________________________//
    856 
    857 }
    858 
    859 } // namespace detail
    860 
    861 // ************************************************************************** //
    862 // **************        execution_monitor::catch_signals      ************** //
    863 // ************************************************************************** //
    864 
    865 int
    866 execution_monitor::catch_signals( unit_test::callback0<int> const& F )
    867 {
    868     using namespace detail;
    869 
    870 #if defined(__CYGWIN__)
    871     p_catch_system_errors.value = false;
    872 #endif
    873 
    874 #ifdef BOOST_TEST_USE_ALT_STACK
    875     if( !!p_use_alt_stack && !m_alt_stack )
    876         m_alt_stack.reset( new char[BOOST_TEST_ALT_STACK_SIZE] );
    877 #else
    878     p_use_alt_stack.value = false;
    879 #endif
    880 
    881     signal_handler local_signal_handler( p_catch_system_errors, p_timeout, p_auto_start_dbg, 
    882                                          !p_use_alt_stack ? 0 : m_alt_stack.get() );
    883 
    884     if( !sigsetjmp( signal_handler::jump_buffer(), 1 ) )
    885         return detail::do_invoke( m_custom_translators , F );
    886     else
    887         throw local_signal_handler.sys_sig();
    888 }
    889 
    890 //____________________________________________________________________________//
    891 
    892 #elif defined(BOOST_SEH_BASED_SIGNAL_HANDLING)
    893 
    894 // ************************************************************************** //
    895 // **************   Microsoft structured exception handling    ************** //
    896 // ************************************************************************** //
    897 
    898 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
    899 namespace { void _set_se_translator( void* ) {} }
    900 #endif
    901 
    902 namespace detail {
    903 
    904 // ************************************************************************** //
    905 // **************    boost::detail::system_signal_exception    ************** //
    906 // ************************************************************************** //
    907 
    908 class system_signal_exception {
    909 public:
    910     // Constructor
    911     explicit            system_signal_exception( execution_monitor* em )
    912     : m_em( em )
    913     , m_se_id( 0 )
    914     , m_fault_address( 0 )
    915     , m_dir( false )
    916     {}
    917 
    918     void                report() const;
    919     int                 operator()( unsigned int id, _EXCEPTION_POINTERS* exps );
    920 
    921 private:
    922     // Data members
    923     execution_monitor*  m_em;
    924 
    925     unsigned int        m_se_id;
    926     void*               m_fault_address;
    927     bool                m_dir;
    928 };
    929 
    930 static void
    931 seh_catch_preventer( unsigned int /* id */, _EXCEPTION_POINTERS* /* exps */ )
    932 {
    933     throw;
    934 }
    935 
    936 //____________________________________________________________________________//
    937 
    938 int
    939 system_signal_exception::operator()( unsigned int id, _EXCEPTION_POINTERS* exps )
    940 {
    941     const unsigned int MSFT_CPP_EXCEPT = 0xE06d7363; // EMSC
    942 
    943     if( !m_em->p_catch_system_errors || (id == MSFT_CPP_EXCEPT) )
    944         return EXCEPTION_CONTINUE_SEARCH;
    945 
    946     if( !!m_em->p_auto_start_dbg && debug::attach_debugger( false ) ) {
    947         m_em->p_catch_system_errors.value = false;
    948         _set_se_translator( &seh_catch_preventer );
    949 
    950         return EXCEPTION_CONTINUE_EXECUTION;
    951     }
    952 
    953     m_se_id = id;
    954     if( m_se_id == EXCEPTION_ACCESS_VIOLATION && exps->ExceptionRecord->NumberParameters == 2 ) {
    955         m_fault_address = (void*)exps->ExceptionRecord->ExceptionInformation[1];
    956         m_dir           = exps->ExceptionRecord->ExceptionInformation[0] == 0;
    957     }
    958 
    959     return EXCEPTION_EXECUTE_HANDLER;
    960 }
    961 
    962 //____________________________________________________________________________//
    963 
    964 void
    965 system_signal_exception::report() const
    966 {
    967     switch( m_se_id ) {
    968     // cases classified as system_fatal_error
    969     case EXCEPTION_ACCESS_VIOLATION: {
    970         if( !m_fault_address )
    971             detail::report_error( execution_exception::system_fatal_error, "memory access violation" );
    972         else
    973             detail::report_error(
    974                 execution_exception::system_fatal_error,
    975                     "memory access violation occurred at address 0x%08lx, while attempting to %s",
    976                     m_fault_address,
    977                     m_dir ? " read inaccessible data"
    978                           : " write to an inaccessible (or protected) address"
    979                     );
    980         break;
    981     }
    982 
    983     case EXCEPTION_ILLEGAL_INSTRUCTION:
    984         detail::report_error( execution_exception::system_fatal_error, "illegal instruction" );
    985         break;
    986 
    987     case EXCEPTION_PRIV_INSTRUCTION:
    988         detail::report_error( execution_exception::system_fatal_error, "tried to execute an instruction whose operation is not allowed in the current machine mode" );
    989         break;
    990 
    991     case EXCEPTION_IN_PAGE_ERROR:
    992         detail::report_error( execution_exception::system_fatal_error, "access to a memory page that is not present" );
    993         break;
    994 
    995     case EXCEPTION_STACK_OVERFLOW:
    996         detail::report_error( execution_exception::system_fatal_error, "stack overflow" );
    997         break;
    998 
    999     case EXCEPTION_NONCONTINUABLE_EXCEPTION:
   1000         detail::report_error( execution_exception::system_fatal_error, "tried to continue execution after a non continuable exception occurred" );
   1001         break;
   1002 
   1003     // cases classified as (non-fatal) system_trap
   1004     case EXCEPTION_DATATYPE_MISALIGNMENT:
   1005         detail::report_error( execution_exception::system_error, "data misalignment" );
   1006         break;
   1007 
   1008     case EXCEPTION_INT_DIVIDE_BY_ZERO:
   1009         detail::report_error( execution_exception::system_error, "integer divide by zero" );
   1010         break;
   1011 
   1012     case EXCEPTION_INT_OVERFLOW:
   1013         detail::report_error( execution_exception::system_error, "integer overflow" );
   1014         break;
   1015 
   1016     case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
   1017         detail::report_error( execution_exception::system_error, "array bounds exceeded" );
   1018         break;
   1019 
   1020     case EXCEPTION_FLT_DIVIDE_BY_ZERO:
   1021         detail::report_error( execution_exception::system_error, "floating point divide by zero" );
   1022         break;
   1023 
   1024     case EXCEPTION_FLT_STACK_CHECK:
   1025         detail::report_error( execution_exception::system_error,
   1026                               "stack overflowed or underflowed as the result of a floating-point operation" );
   1027         break;
   1028 
   1029     case EXCEPTION_FLT_DENORMAL_OPERAND:
   1030         detail::report_error( execution_exception::system_error,
   1031                               "operand of floating point operation is denormal" );
   1032         break;
   1033 
   1034 # if 0 // !! ?? 
   1035     case EXCEPTION_FLT_INEXACT_RESULT:
   1036         detail::report_error( execution_exception::system_error,
   1037                               "result of a floating-point operation cannot be represented exactly" );
   1038         break;
   1039 #endif
   1040 
   1041     case EXCEPTION_FLT_OVERFLOW:
   1042         detail::report_error( execution_exception::system_error,
   1043                               "exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type" );
   1044         break;
   1045 
   1046     case EXCEPTION_FLT_UNDERFLOW:
   1047         detail::report_error( execution_exception::system_error,
   1048                               "exponent of a floating-point operation is less than the magnitude allowed by the corresponding type" );
   1049         break;
   1050 
   1051     case EXCEPTION_FLT_INVALID_OPERATION:
   1052         detail::report_error( execution_exception::system_error, "floating point error" );
   1053         break;
   1054 
   1055     case EXCEPTION_BREAKPOINT:
   1056         detail::report_error( execution_exception::system_error, "breakpoint encountered" );
   1057         break;
   1058 
   1059     default:
   1060         detail::report_error( execution_exception::system_error, "unrecognized exception. Id: 0x%08lx", m_se_id );
   1061         break;
   1062     }
   1063 }
   1064 
   1065 //____________________________________________________________________________//
   1066 
   1067 // ************************************************************************** //
   1068 // **************          assert_reporting_function           ************** //
   1069 // ************************************************************************** //
   1070 
   1071 int BOOST_TEST_CALL_DECL
   1072 assert_reporting_function( int reportType, char* userMessage, int* )
   1073 {
   1074     switch( reportType ) {
   1075     case BOOST_TEST_CRT_ASSERT:
   1076         detail::report_error( execution_exception::user_error, userMessage );
   1077 
   1078         return 1; // return value and retVal are not important since we never reach this line
   1079     case BOOST_TEST_CRT_ERROR:
   1080         detail::report_error( execution_exception::system_error, userMessage );
   1081 
   1082         return 1; // return value and retVal are not important since we never reach this line
   1083     default:
   1084         return 0; // use usual reporting method
   1085     }
   1086 } // assert_reporting_function
   1087 
   1088 //____________________________________________________________________________//
   1089 
   1090 void BOOST_TEST_CALL_DECL
   1091 invalid_param_handler( wchar_t const* /* expr */, 
   1092                        wchar_t const* /* func */, 
   1093                        wchar_t const* /* file */, 
   1094                        unsigned int   /* line */,
   1095                        uintptr_t      /* reserved */)
   1096 {
   1097     detail::report_error( execution_exception::user_error, 
   1098                           "Invalid parameter detected by C runtime library" );
   1099 }
   1100 
   1101 //____________________________________________________________________________//
   1102 
   1103 void BOOST_TEST_CALL_DECL
   1104 switch_fp_exceptions( bool on_off )
   1105 {
   1106     if( !on_off )
   1107         _clearfp();
   1108 
   1109     int cw = ::_controlfp( 0, 0 );
   1110 
   1111     int exceptions_mask = EM_INVALID|EM_DENORMAL|EM_ZERODIVIDE|EM_OVERFLOW|EM_UNDERFLOW;
   1112 
   1113     if( on_off )
   1114         cw &= ~exceptions_mask; // Set the exception masks on, turn exceptions off
   1115     else
   1116         cw |= exceptions_mask;  // Set the exception masks off, turn exceptions on
   1117 
   1118     if( on_off )
   1119         _clearfp();
   1120         
   1121     // Set the control word
   1122     ::_controlfp( cw, MCW_EM );
   1123 }
   1124 
   1125 //____________________________________________________________________________//
   1126 
   1127 } // namespace detail
   1128 
   1129 // ************************************************************************** //
   1130 // **************        execution_monitor::catch_signals      ************** //
   1131 // ************************************************************************** //
   1132 
   1133 int
   1134 execution_monitor::catch_signals( unit_test::callback0<int> const& F )
   1135 {
   1136     _invalid_parameter_handler old_iph = _invalid_parameter_handler();
   1137     BOOST_TEST_CRT_HOOK_TYPE old_crt_hook = 0;
   1138 
   1139     if( !p_catch_system_errors )
   1140         _set_se_translator( &detail::seh_catch_preventer );
   1141     else {
   1142         if( !!p_detect_fp_exceptions )
   1143             detail::switch_fp_exceptions( true );
   1144 
   1145        old_crt_hook = BOOST_TEST_CRT_SET_HOOK( &detail::assert_reporting_function );
   1146 
   1147        old_iph = _set_invalid_parameter_handler( 
   1148            reinterpret_cast<_invalid_parameter_handler>( &detail::invalid_param_handler ) );
   1149     }
   1150 
   1151     detail::system_signal_exception SSE( this );
   1152     
   1153     int ret_val = 0;
   1154 
   1155     __try {
   1156         __try {
   1157             ret_val = detail::do_invoke( m_custom_translators, F );
   1158         }
   1159         __except( SSE( GetExceptionCode(), GetExceptionInformation() ) ) {
   1160             throw SSE;
   1161         }
   1162     }
   1163     __finally {
   1164         if( !!p_catch_system_errors ) {
   1165             if( !!p_detect_fp_exceptions )
   1166                 detail::switch_fp_exceptions( false );
   1167 
   1168             BOOST_TEST_CRT_SET_HOOK( old_crt_hook );
   1169 
   1170            _set_invalid_parameter_handler( old_iph );
   1171         }
   1172     }
   1173 
   1174     return ret_val;
   1175 }
   1176 
   1177 //____________________________________________________________________________//
   1178 
   1179 #else  // default signal handler
   1180 
   1181 namespace detail {
   1182 
   1183 class system_signal_exception {
   1184 public:
   1185     void   report() const {}
   1186 };
   1187 
   1188 } // namespace detail
   1189 
   1190 int
   1191 execution_monitor::catch_signals( unit_test::callback0<int> const& F )
   1192 {
   1193     return detail::do_invoke( m_custom_translators , F );
   1194 }
   1195 
   1196 //____________________________________________________________________________//
   1197 
   1198 #endif  // choose signal handler
   1199 
   1200 // ************************************************************************** //
   1201 // **************          execution_monitor::execute          ************** //
   1202 // ************************************************************************** //
   1203 
   1204 int
   1205 execution_monitor::execute( unit_test::callback0<int> const& F )
   1206 {
   1207     if( debug::under_debugger() )
   1208         p_catch_system_errors.value = false;
   1209 
   1210     try {
   1211         return catch_signals( F );
   1212     }
   1213 
   1214     //  Catch-clause reference arguments are a bit different from function
   1215     //  arguments (ISO 15.3 paragraphs 18 & 19).  Apparently const isn't
   1216     //  required.  Programmers ask for const anyhow, so we supply it.  That's
   1217     //  easier than answering questions about non-const usage.
   1218 
   1219     catch( char const* ex )
   1220       { detail::report_error( execution_exception::cpp_exception_error,
   1221                               "C string: %s", ex ); }
   1222     catch( std::string const& ex )
   1223       { detail::report_error( execution_exception::cpp_exception_error, 
   1224                               "std::string: %s", ex.c_str() ); }
   1225 
   1226     //  std:: exceptions
   1227 
   1228     catch( std::bad_alloc const& ex )
   1229       { detail::report_error( execution_exception::cpp_exception_error, 
   1230                               current_exception_cast<boost::exception const>(),
   1231                               "std::bad_alloc: %s", ex.what() ); }
   1232 
   1233 #if BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
   1234     catch( std::bad_cast const& ex )
   1235       { detail::report_error( execution_exception::cpp_exception_error, 
   1236                               current_exception_cast<boost::exception const>(),
   1237                               "std::bad_cast" ); }
   1238     catch( std::bad_typeid const& ex )
   1239       { detail::report_error( execution_exception::cpp_exception_error, 
   1240                               current_exception_cast<boost::exception const>(),
   1241                               "std::bad_typeid" ); }
   1242 #else
   1243     catch( std::bad_cast const& ex )
   1244       { detail::report_error( execution_exception::cpp_exception_error, 
   1245                               current_exception_cast<boost::exception const>(),
   1246                               "std::bad_cast: %s", ex.what() ); }
   1247     catch( std::bad_typeid const& ex )
   1248       { detail::report_error( execution_exception::cpp_exception_error, 
   1249                               current_exception_cast<boost::exception const>(),
   1250                               "std::bad_typeid: %s", ex.what() ); }
   1251 #endif
   1252 
   1253     catch( std::bad_exception const& ex )
   1254       { detail::report_error( execution_exception::cpp_exception_error, 
   1255                               current_exception_cast<boost::exception const>(),
   1256                               "std::bad_exception: %s", ex.what() ); }
   1257     catch( std::domain_error const& ex )
   1258       { detail::report_error( execution_exception::cpp_exception_error, 
   1259                               current_exception_cast<boost::exception const>(),
   1260                               "std::domain_error: %s", ex.what() ); }
   1261     catch( std::invalid_argument const& ex )
   1262       { detail::report_error( execution_exception::cpp_exception_error, 
   1263                               current_exception_cast<boost::exception const>(),
   1264                               "std::invalid_argument: %s", ex.what() ); }
   1265     catch( std::length_error const& ex )
   1266       { detail::report_error( execution_exception::cpp_exception_error, 
   1267                               current_exception_cast<boost::exception const>(),
   1268                               "std::length_error: %s", ex.what() ); }
   1269     catch( std::out_of_range const& ex )
   1270       { detail::report_error( execution_exception::cpp_exception_error, 
   1271                               current_exception_cast<boost::exception const>(),
   1272                               "std::out_of_range: %s", ex.what() ); }
   1273     catch( std::range_error const& ex )
   1274       { detail::report_error( execution_exception::cpp_exception_error, 
   1275                               current_exception_cast<boost::exception const>(),
   1276                               "std::range_error: %s", ex.what() ); }
   1277     catch( std::overflow_error const& ex )
   1278       { detail::report_error( execution_exception::cpp_exception_error, 
   1279                               current_exception_cast<boost::exception const>(),
   1280                               "std::overflow_error: %s", ex.what() ); }
   1281     catch( std::underflow_error const& ex )
   1282       { detail::report_error( execution_exception::cpp_exception_error, 
   1283                               current_exception_cast<boost::exception const>(),
   1284                               "std::underflow_error: %s", ex.what() ); }
   1285     catch( std::logic_error const& ex )
   1286       { detail::report_error( execution_exception::cpp_exception_error, 
   1287                               current_exception_cast<boost::exception const>(),
   1288                               "std::logic_error: %s", ex.what() ); }
   1289     catch( std::runtime_error const& ex )
   1290       { detail::report_error( execution_exception::cpp_exception_error, 
   1291                               current_exception_cast<boost::exception const>(),
   1292                               "std::runtime_error: %s", ex.what() ); }
   1293     catch( std::exception const& ex )
   1294       { detail::report_error( execution_exception::cpp_exception_error, 
   1295                               current_exception_cast<boost::exception const>(),
   1296                               "std::exception: %s", ex.what() ); }
   1297 
   1298     catch( boost::exception const& ex )
   1299     { detail::report_error( execution_exception::cpp_exception_error, 
   1300                             &ex,
   1301                             "unknown boost::exception" ); }
   1302 
   1303     // system errors
   1304     catch( system_error const& ex )
   1305       { detail::report_error( execution_exception::cpp_exception_error, 
   1306                               "system_error produced by: %s: %s", ex.p_failed_exp.get(), std::strerror( ex.p_errno ) ); }
   1307     catch( detail::system_signal_exception const& ex )
   1308       { ex.report(); }
   1309 
   1310     // not an error
   1311     catch( execution_aborted const& )
   1312       { return 0; }
   1313 
   1314     // just forward
   1315     catch( execution_exception const& )
   1316       { throw; }
   1317 
   1318     // unknown error
   1319     catch( ... )
   1320       { detail::report_error( execution_exception::cpp_exception_error, "unknown type" ); }
   1321 
   1322     return 0;  // never reached; supplied to quiet compiler warnings
   1323 } // execute
   1324 
   1325 //____________________________________________________________________________//
   1326 
   1327 // ************************************************************************** //
   1328 // **************                  system_error                ************** //
   1329 // ************************************************************************** //
   1330 
   1331 system_error::system_error( char const* exp )
   1332 #ifdef UNDER_CE
   1333 : p_errno( GetLastError() )
   1334 #else
   1335 : p_errno( errno )
   1336 #endif
   1337 , p_failed_exp( exp )
   1338 {}
   1339 
   1340 //____________________________________________________________________________//
   1341 
   1342 // ************************************************************************** //
   1343 // **************              execution_exception             ************** //
   1344 // ************************************************************************** //
   1345 
   1346 execution_exception::execution_exception( error_code ec_, const_string what_msg_, location const& location_ )
   1347 : m_error_code( ec_ )
   1348 , m_what( what_msg_.empty() ? BOOST_TEST_L( "uncaught exception, system error or abort requested" ) : what_msg_ )
   1349 , m_location( location_ )
   1350 {}
   1351 
   1352 //____________________________________________________________________________//
   1353 
   1354 execution_exception::location::location( char const* file_name, size_t line_num, char const* func )
   1355 : m_file_name( file_name ? file_name : "unknown location" )
   1356 , m_line_num( line_num )
   1357 , m_function( func )
   1358 {}
   1359 
   1360 //____________________________________________________________________________//
   1361 
   1362 } // namespace boost
   1363 
   1364 #include <boost/test/detail/enable_warnings.hpp>
   1365 
   1366 #endif // BOOST_TEST_EXECUTION_MONITOR_IPP_012205GER
   1367 
   1368