File indexing completed on 2025-09-18 09:06:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #ifndef BOOST_TEST_EXECUTION_MONITOR_IPP_012205GER
0022 #define BOOST_TEST_EXECUTION_MONITOR_IPP_012205GER
0023
0024
0025 #include <boost/test/detail/config.hpp>
0026 #include <boost/test/detail/throw_exception.hpp>
0027 #include <boost/test/execution_monitor.hpp>
0028 #include <boost/test/debug.hpp>
0029
0030
0031 #include <boost/cstdlib.hpp> // for exit codes
0032 #include <boost/config.hpp> // for workarounds
0033 #include <boost/core/ignore_unused.hpp> // for ignore_unused
0034 #ifndef BOOST_NO_EXCEPTIONS
0035 #include <boost/exception/get_error_info.hpp> // for get_error_info
0036 #include <boost/exception/current_exception_cast.hpp> // for current_exception_cast
0037 #include <boost/exception/diagnostic_information.hpp>
0038 #endif
0039
0040
0041 #include <string> // for std::string
0042 #include <new> // for std::bad_alloc
0043 #include <typeinfo> // for std::bad_cast, std::bad_typeid
0044 #include <exception> // for std::exception, std::bad_exception
0045 #include <stdexcept> // for std exception hierarchy
0046 #include <cstring> // for C string API
0047 #include <cassert> // for assert
0048 #include <cstddef> // for NULL
0049 #include <cstdio> // for vsnprintf
0050 #include <stdio.h>
0051 #include <cstdarg> // for varargs
0052 #include <stdarg.h>
0053 #include <cmath> // for ceil
0054
0055 #include <iostream> // for varargs
0056
0057 #ifdef BOOST_NO_STDC_NAMESPACE
0058 namespace std { using ::strerror; using ::strlen; using ::strncat; using ::ceil; }
0059 #endif
0060
0061
0062 #if defined(__SUNPRO_CC) || defined(__SunOS) || defined(__QNXNTO__) || defined(__VXWORKS__)
0063 using std::va_list;
0064 #endif
0065
0066 #if defined(__VXWORKS__)
0067 # define BOOST_TEST_LIMITED_SIGNAL_DETAILS
0068 #endif
0069
0070 #ifdef BOOST_SEH_BASED_SIGNAL_HANDLING
0071
0072 # if !defined(_WIN32_WINNT)
0073 # define _WIN32_WINNT 0x0501
0074 # endif
0075
0076 # include <windows.h>
0077
0078 # if defined(__MWERKS__) || (defined(_MSC_VER) && !defined(UNDER_CE))
0079 # include <eh.h>
0080 # endif
0081
0082 # if defined(BOOST_BORLANDC) && BOOST_BORLANDC >= 0x560 || defined(__MWERKS__)
0083 # include <stdint.h>
0084 # endif
0085
0086 # if defined(BOOST_BORLANDC) && BOOST_BORLANDC < 0x560
0087 typedef unsigned uintptr_t;
0088 # endif
0089
0090 # if defined(UNDER_CE) && BOOST_WORKAROUND(_MSC_VER, < 1500 )
0091 typedef void* uintptr_t;
0092 # elif defined(UNDER_CE)
0093 # include <crtdefs.h>
0094 # endif
0095
0096 # if !defined(NDEBUG) && defined(_MSC_VER) && !defined(UNDER_CE)
0097 # include <crtdbg.h>
0098 # define BOOST_TEST_CRT_HOOK_TYPE _CRT_REPORT_HOOK
0099 # define BOOST_TEST_CRT_ASSERT _CRT_ASSERT
0100 # define BOOST_TEST_CRT_ERROR _CRT_ERROR
0101 # define BOOST_TEST_CRT_SET_HOOK(H) _CrtSetReportHook(H)
0102 # else
0103 # define BOOST_TEST_CRT_HOOK_TYPE void*
0104 # define BOOST_TEST_CRT_ASSERT 2
0105 # define BOOST_TEST_CRT_ERROR 1
0106 # define BOOST_TEST_CRT_SET_HOOK(H) (void*)(H)
0107 # endif
0108
0109 # if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
0110 # define BOOST_TEST_WIN32_WAITABLE_TIMERS
0111 # endif
0112
0113 # if (!BOOST_WORKAROUND(_MSC_VER, >= 1400 ) && \
0114 !defined(BOOST_COMO)) || defined(UNDER_CE)
0115
0116 typedef void* _invalid_parameter_handler;
0117
0118 inline _invalid_parameter_handler
0119 _set_invalid_parameter_handler( _invalid_parameter_handler arg )
0120 {
0121 return arg;
0122 }
0123
0124 # endif
0125
0126 # if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0564)) || defined(UNDER_CE)
0127
0128 namespace { void _set_se_translator( void* ) {} }
0129
0130 # endif
0131
0132 #elif defined(BOOST_HAS_SIGACTION)
0133
0134 # define BOOST_SIGACTION_BASED_SIGNAL_HANDLING
0135
0136 # include <unistd.h>
0137 # include <signal.h>
0138 # include <setjmp.h>
0139
0140 # if defined(__FreeBSD__)
0141
0142 # include <osreldate.h>
0143
0144 # ifndef SIGPOLL
0145 # define SIGPOLL SIGIO
0146 # endif
0147
0148 # if (__FreeBSD_version < 70100)
0149
0150 # define ILL_ILLADR 0
0151 # define ILL_PRVOPC ILL_PRIVIN_FAULT
0152 # define ILL_ILLOPN 2
0153 # define ILL_COPROC ILL_FPOP_FAULT
0154
0155 # define BOOST_TEST_LIMITED_SIGNAL_DETAILS
0156
0157 # endif
0158 # endif
0159
0160 # if defined(__ANDROID__)
0161 # include <android/api-level.h>
0162 # endif
0163
0164
0165 # if !defined(__CYGWIN__) && !defined(__QNXNTO__) && !defined(__bgq__) && \
0166 (!defined(__ANDROID__) || __ANDROID_API__ >= 8) && !defined(__wasm__) && \
0167 !defined(BOOST_TEST_DISABLE_ALT_STACK)
0168 # define BOOST_TEST_USE_ALT_STACK
0169 # endif
0170
0171 # if defined(SIGPOLL) && !defined(__CYGWIN__) && \
0172 !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && \
0173 !defined(__NetBSD__) && \
0174 !defined(__QNXNTO__)
0175 # define BOOST_TEST_CATCH_SIGPOLL
0176 # endif
0177
0178 # ifdef BOOST_TEST_USE_ALT_STACK
0179 # define BOOST_TEST_ALT_STACK_SIZE SIGSTKSZ
0180 # endif
0181
0182
0183 #else
0184
0185 # define BOOST_NO_SIGNAL_HANDLING
0186
0187 #endif
0188
0189 #ifndef UNDER_CE
0190 #include <errno.h>
0191 #endif
0192
0193 #if !defined(BOOST_NO_TYPEID) && !defined(BOOST_NO_RTTI)
0194 # include <boost/core/demangle.hpp>
0195 #endif
0196
0197 #if (!defined(BOOST_MSSTL_VERSION) || (BOOST_MSSTL_VERSION >= 120)) && (!defined(__GLIBC__) || ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2))))
0198
0199 # if (defined(__GLIBC__) && !((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 18)))) || defined(__APPLE__)
0200 # ifndef __STDC_FORMAT_MACROS
0201 # define __STDC_FORMAT_MACROS 1
0202 # define BOOST_TEST_DEFINED_STDC_FORMAT_MACROS
0203 # endif
0204 # endif
0205 # include <inttypes.h>
0206 # define BOOST_TEST_PRIxPTR PRIxPTR
0207 # ifdef BOOST_TEST_DEFINED_STDC_FORMAT_MACROS
0208 # undef __STDC_FORMAT_MACROS
0209 # endif
0210 #endif
0211
0212 #ifndef BOOST_TEST_PRIxPTR
0213 # ifdef __has_include
0214 # if __has_include(<cinttypes>)
0215 # include <cinttypes>
0216 # define BOOST_TEST_PRIxPTR PRIxPTR
0217 # endif
0218 # endif
0219 #endif
0220
0221 #ifndef BOOST_TEST_PRIxPTR
0222 # define BOOST_TEST_PRIxPTR "08lx"
0223 #endif
0224
0225 #include <boost/test/detail/suppress_warnings.hpp>
0226
0227
0228
0229 namespace boost {
0230
0231
0232
0233
0234
0235 #ifdef BOOST_NO_EXCEPTIONS
0236 void throw_exception( std::exception const & e ) { abort(); }
0237 #endif
0238
0239
0240
0241
0242
0243 namespace detail {
0244
0245 #ifdef BOOST_BORLANDC
0246 # define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) std::vsnprintf( (a1), (a2), (a3), (a4) )
0247 #elif BOOST_WORKAROUND(_MSC_VER, <= 1310) || \
0248 BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3000)) || \
0249 defined(UNDER_CE) || \
0250 (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
0251 # define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) _vsnprintf( (a1), (a2), (a3), (a4) )
0252 #else
0253 # define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) vsnprintf( (a1), (a2), (a3), (a4) )
0254 #endif
0255
0256
0257
0258 #if __GNUC__ >= 3 || defined(BOOST_EMBTC)
0259 #define BOOST_TEST_PRINTF_ATTRIBUTE_CHECK(x, y) __attribute__((__format__ (__printf__, x, y)))
0260 #else
0261 #define BOOST_TEST_PRINTF_ATTRIBUTE_CHECK(x, y)
0262 #endif
0263
0264 #ifndef BOOST_NO_EXCEPTIONS
0265
0266 template <typename ErrorInfo>
0267 typename ErrorInfo::value_type
0268 extract( boost::exception const* ex )
0269 {
0270 if( !ex )
0271 return 0;
0272
0273 typename ErrorInfo::value_type const * val = boost::get_error_info<ErrorInfo>( *ex );
0274
0275 return val ? *val : 0;
0276 }
0277
0278
0279
0280 static void
0281 BOOST_TEST_PRINTF_ATTRIBUTE_CHECK(3, 0)
0282 report_error( execution_exception::error_code ec, boost::exception const* be, char const* format, va_list* args )
0283 {
0284 static const int REPORT_ERROR_BUFFER_SIZE = 4096;
0285 static char buf[REPORT_ERROR_BUFFER_SIZE];
0286
0287 BOOST_TEST_VSNPRINTF( buf, sizeof(buf)-1, format, *args );
0288 buf[sizeof(buf)-1] = 0;
0289
0290 va_end( *args );
0291
0292 BOOST_TEST_I_THROW(execution_exception( ec, buf, execution_exception::location( extract<throw_file>( be ),
0293 (size_t)extract<throw_line>( be ),
0294 extract<throw_function>( be ) ) ));
0295 }
0296
0297
0298
0299 static void
0300 BOOST_TEST_PRINTF_ATTRIBUTE_CHECK(3, 4)
0301 report_error( execution_exception::error_code ec, boost::exception const* be, char const* format, ... )
0302 {
0303 va_list args;
0304 va_start( args, format );
0305
0306 report_error( ec, be, format, &args );
0307 }
0308
0309 #endif
0310
0311
0312
0313 static void
0314 BOOST_TEST_PRINTF_ATTRIBUTE_CHECK(2, 3)
0315 report_error( execution_exception::error_code ec, char const* format, ... )
0316 {
0317 va_list args;
0318 va_start( args, format );
0319
0320 report_error( ec, 0, format, &args );
0321 }
0322
0323
0324
0325 template<typename Tr,typename Functor>
0326 inline int
0327 do_invoke( Tr const& tr, Functor const& F )
0328 {
0329 return tr ? (*tr)( F ) : F();
0330 }
0331
0332
0333
0334 struct fpe_except_guard {
0335 explicit fpe_except_guard( unsigned detect_fpe )
0336 : m_detect_fpe( detect_fpe )
0337 {
0338
0339 m_previously_enabled = fpe::disable( fpe::BOOST_FPE_ALL );
0340 if( m_previously_enabled != fpe::BOOST_FPE_INV && detect_fpe != fpe::BOOST_FPE_OFF )
0341 fpe::enable( detect_fpe );
0342 }
0343 ~fpe_except_guard()
0344 {
0345 if( m_detect_fpe != fpe::BOOST_FPE_OFF )
0346 fpe::disable( m_detect_fpe );
0347 if( m_previously_enabled != fpe::BOOST_FPE_INV )
0348 fpe::enable( m_previously_enabled );
0349 }
0350
0351 unsigned m_detect_fpe;
0352 unsigned m_previously_enabled;
0353 };
0354
0355
0356
0357
0358
0359
0360 #if !defined(BOOST_NO_TYPEID) && !defined(BOOST_NO_RTTI)
0361 template<typename T>
0362 std::string
0363 typeid_name( T const& t )
0364 {
0365 return boost::core::demangle(typeid(t).name());
0366 }
0367 #endif
0368
0369 }
0370
0371 #if defined(BOOST_SIGACTION_BASED_SIGNAL_HANDLING)
0372
0373
0374
0375
0376
0377 namespace detail {
0378
0379
0380
0381
0382
0383 class system_signal_exception {
0384 public:
0385
0386 system_signal_exception()
0387 : m_sig_info( 0 )
0388 , m_context( 0 )
0389 {}
0390
0391
0392 void operator()( siginfo_t* i, void* c )
0393 {
0394 m_sig_info = i;
0395 m_context = c;
0396 }
0397 void report() const;
0398
0399 private:
0400
0401 siginfo_t* m_sig_info;
0402 void* m_context;
0403 };
0404
0405
0406
0407 void
0408 system_signal_exception::report() const
0409 {
0410 if( !m_sig_info )
0411 return;
0412
0413 switch( m_sig_info->si_code ) {
0414 #ifdef __VXWORKS__
0415
0416 #define si_addr si_value.sival_int
0417 #define si_band si_value.sival_int
0418 #else
0419 case SI_USER:
0420 report_error( execution_exception::system_error,
0421 "signal: generated by kill() (or family); uid=%d; pid=%d",
0422 (int)m_sig_info->si_uid, (int)m_sig_info->si_pid );
0423 break;
0424 #endif
0425 case SI_QUEUE:
0426 report_error( execution_exception::system_error,
0427 "signal: sent by sigqueue()" );
0428 break;
0429 case SI_TIMER:
0430 report_error( execution_exception::system_error,
0431 "signal: the expiration of a timer set by timer_settimer()" );
0432 break;
0433
0434 #ifdef SI_ASYNCIO
0435 case SI_ASYNCIO:
0436 report_error( execution_exception::system_error,
0437 "signal: generated by the completion of an asynchronous I/O request" );
0438 break;
0439 #endif
0440 #ifdef SI_MESGQ
0441 case SI_MESGQ:
0442 report_error( execution_exception::system_error,
0443 "signal: generated by the the arrival of a message on an empty message queue" );
0444 break;
0445 #endif
0446 default:
0447 break;
0448 }
0449
0450 switch( m_sig_info->si_signo ) {
0451 case SIGILL:
0452 switch( m_sig_info->si_code ) {
0453 #ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
0454 case ILL_ILLOPC:
0455 report_error( execution_exception::system_fatal_error,
0456 "signal: illegal opcode; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0457 (uintptr_t) m_sig_info->si_addr );
0458 break;
0459 case ILL_ILLTRP:
0460 report_error( execution_exception::system_fatal_error,
0461 "signal: illegal trap; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0462 (uintptr_t) m_sig_info->si_addr );
0463 break;
0464 case ILL_PRVREG:
0465 report_error( execution_exception::system_fatal_error,
0466 "signal: privileged register; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0467 (uintptr_t) m_sig_info->si_addr );
0468 break;
0469 case ILL_BADSTK:
0470 report_error( execution_exception::system_fatal_error,
0471 "signal: internal stack error; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0472 (uintptr_t) m_sig_info->si_addr );
0473 break;
0474 #endif
0475 case ILL_ILLOPN:
0476 report_error( execution_exception::system_fatal_error,
0477 "signal: illegal operand; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0478 (uintptr_t) m_sig_info->si_addr );
0479 break;
0480 case ILL_ILLADR:
0481 report_error( execution_exception::system_fatal_error,
0482 "signal: illegal addressing mode; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0483 (uintptr_t) m_sig_info->si_addr );
0484 break;
0485 case ILL_PRVOPC:
0486 report_error( execution_exception::system_fatal_error,
0487 "signal: privileged opcode; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0488 (uintptr_t) m_sig_info->si_addr );
0489 break;
0490 case ILL_COPROC:
0491 report_error( execution_exception::system_fatal_error,
0492 "signal: co-processor error; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0493 (uintptr_t) m_sig_info->si_addr );
0494 break;
0495 default:
0496 report_error( execution_exception::system_fatal_error,
0497 "signal: SIGILL, si_code: %d (illegal instruction; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR ")",
0498 m_sig_info->si_code, (uintptr_t) m_sig_info->si_addr );
0499 break;
0500 }
0501 break;
0502
0503 case SIGFPE:
0504 switch( m_sig_info->si_code ) {
0505 case FPE_INTDIV:
0506 report_error( execution_exception::system_error,
0507 "signal: integer divide by zero; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0508 (uintptr_t) m_sig_info->si_addr );
0509 break;
0510 case FPE_INTOVF:
0511 report_error( execution_exception::system_error,
0512 "signal: integer overflow; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0513 (uintptr_t) m_sig_info->si_addr );
0514 break;
0515 case FPE_FLTDIV:
0516 report_error( execution_exception::system_error,
0517 "signal: floating point divide by zero; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0518 (uintptr_t) m_sig_info->si_addr );
0519 break;
0520 case FPE_FLTOVF:
0521 report_error( execution_exception::system_error,
0522 "signal: floating point overflow; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0523 (uintptr_t) m_sig_info->si_addr );
0524 break;
0525 case FPE_FLTUND:
0526 report_error( execution_exception::system_error,
0527 "signal: floating point underflow; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0528 (uintptr_t) m_sig_info->si_addr );
0529 break;
0530 case FPE_FLTRES:
0531 report_error( execution_exception::system_error,
0532 "signal: floating point inexact result; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0533 (uintptr_t) m_sig_info->si_addr );
0534 break;
0535 case FPE_FLTINV:
0536 report_error( execution_exception::system_error,
0537 "signal: invalid floating point operation; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0538 (uintptr_t) m_sig_info->si_addr );
0539 break;
0540 case FPE_FLTSUB:
0541 report_error( execution_exception::system_error,
0542 "signal: subscript out of range; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR,
0543 (uintptr_t) m_sig_info->si_addr );
0544 break;
0545 default:
0546 report_error( execution_exception::system_error,
0547 "signal: SIGFPE, si_code: %d (errnoneous arithmetic operations; address of failing instruction: 0x%" BOOST_TEST_PRIxPTR ")",
0548 m_sig_info->si_code, (uintptr_t) m_sig_info->si_addr );
0549 break;
0550 }
0551 break;
0552
0553 case SIGSEGV:
0554 switch( m_sig_info->si_code ) {
0555 #ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
0556 case SEGV_MAPERR:
0557 report_error( execution_exception::system_fatal_error,
0558 "memory access violation at address: 0x%" BOOST_TEST_PRIxPTR ": no mapping at fault address",
0559 (uintptr_t) m_sig_info->si_addr );
0560 break;
0561 case SEGV_ACCERR:
0562 report_error( execution_exception::system_fatal_error,
0563 "memory access violation at address: 0x%" BOOST_TEST_PRIxPTR ": invalid permissions",
0564 (uintptr_t) m_sig_info->si_addr );
0565 break;
0566 #endif
0567 default:
0568 report_error( execution_exception::system_fatal_error,
0569 "signal: SIGSEGV, si_code: %d (memory access violation at address: 0x%" BOOST_TEST_PRIxPTR ")",
0570 m_sig_info->si_code, (uintptr_t) m_sig_info->si_addr );
0571 break;
0572 }
0573 break;
0574
0575 case SIGBUS:
0576 switch( m_sig_info->si_code ) {
0577 #ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
0578 case BUS_ADRALN:
0579 report_error( execution_exception::system_fatal_error,
0580 "memory access violation at address: 0x%" BOOST_TEST_PRIxPTR ": invalid address alignment",
0581 (uintptr_t) m_sig_info->si_addr );
0582 break;
0583 case BUS_ADRERR:
0584 report_error( execution_exception::system_fatal_error,
0585 "memory access violation at address: 0x%" BOOST_TEST_PRIxPTR ": non-existent physical address",
0586 (uintptr_t) m_sig_info->si_addr );
0587 break;
0588 case BUS_OBJERR:
0589 report_error( execution_exception::system_fatal_error,
0590 "memory access violation at address: 0x%" BOOST_TEST_PRIxPTR ": object specific hardware error",
0591 (uintptr_t) m_sig_info->si_addr );
0592 break;
0593 #endif
0594 default:
0595 report_error( execution_exception::system_fatal_error,
0596 "signal: SIGSEGV, si_code: %d (memory access violation at address: 0x%" BOOST_TEST_PRIxPTR ")",
0597 m_sig_info->si_code, (uintptr_t) m_sig_info->si_addr );
0598 break;
0599 }
0600 break;
0601
0602 #if defined(BOOST_TEST_CATCH_SIGPOLL)
0603
0604 case SIGPOLL:
0605 switch( m_sig_info->si_code ) {
0606 #ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
0607 case POLL_IN:
0608 report_error( execution_exception::system_error,
0609 "data input available; band event %d",
0610 (int)m_sig_info->si_band );
0611 break;
0612 case POLL_OUT:
0613 report_error( execution_exception::system_error,
0614 "output buffers available; band event %d",
0615 (int)m_sig_info->si_band );
0616 break;
0617 case POLL_MSG:
0618 report_error( execution_exception::system_error,
0619 "input message available; band event %d",
0620 (int)m_sig_info->si_band );
0621 break;
0622 case POLL_ERR:
0623 report_error( execution_exception::system_error,
0624 "i/o error; band event %d",
0625 (int)m_sig_info->si_band );
0626 break;
0627 case POLL_PRI:
0628 report_error( execution_exception::system_error,
0629 "high priority input available; band event %d",
0630 (int)m_sig_info->si_band );
0631 break;
0632 #if defined(POLL_ERR) && defined(POLL_HUP) && (POLL_ERR - POLL_HUP)
0633 case POLL_HUP:
0634 report_error( execution_exception::system_error,
0635 "device disconnected; band event %d",
0636 (int)m_sig_info->si_band );
0637 break;
0638 #endif
0639 #endif
0640 default:
0641 report_error( execution_exception::system_error,
0642 "signal: SIGPOLL, si_code: %d (asynchronous I/O event occurred; band event %d)",
0643 m_sig_info->si_code, (int)m_sig_info->si_band );
0644 break;
0645 }
0646 break;
0647
0648 #endif
0649
0650 case SIGABRT:
0651 report_error( execution_exception::system_error,
0652 "signal: SIGABRT (application abort requested)" );
0653 break;
0654
0655 case SIGALRM:
0656 report_error( execution_exception::timeout_error,
0657 "signal: SIGALRM (timeout while executing function)" );
0658 break;
0659
0660 default:
0661 report_error( execution_exception::system_error,
0662 "unrecognized signal %d", m_sig_info->si_signo );
0663 }
0664 }
0665
0666
0667
0668
0669
0670
0671
0672
0673 extern "C" {
0674 static void boost_execution_monitor_jumping_signal_handler( int sig, siginfo_t* info, void* context );
0675 static void boost_execution_monitor_attaching_signal_handler( int sig, siginfo_t* info, void* context );
0676 }
0677
0678 class signal_action {
0679 typedef struct sigaction* sigaction_ptr;
0680 public:
0681
0682 signal_action();
0683 signal_action( int sig, bool install, bool attach_dbg, char* alt_stack );
0684 ~signal_action();
0685
0686 private:
0687
0688 int m_sig;
0689 bool m_installed;
0690 struct sigaction m_new_action;
0691 struct sigaction m_old_action;
0692 };
0693
0694
0695
0696 signal_action::signal_action()
0697 : m_installed( false )
0698 {}
0699
0700
0701
0702 signal_action::signal_action( int sig, bool install, bool attach_dbg, char* alt_stack )
0703 : m_sig( sig )
0704 , m_installed( install )
0705 {
0706 if( !install )
0707 return;
0708
0709 std::memset( &m_new_action, 0, sizeof(struct sigaction) );
0710
0711 BOOST_TEST_SYS_ASSERT( ::sigaction( m_sig , sigaction_ptr(), &m_new_action ) != -1 );
0712
0713 if( m_new_action.sa_sigaction || m_new_action.sa_handler ) {
0714 m_installed = false;
0715 return;
0716 }
0717
0718 m_new_action.sa_flags |= SA_SIGINFO;
0719 m_new_action.sa_sigaction = attach_dbg ? &boost_execution_monitor_attaching_signal_handler
0720 : &boost_execution_monitor_jumping_signal_handler;
0721 BOOST_TEST_SYS_ASSERT( sigemptyset( &m_new_action.sa_mask ) != -1 );
0722
0723 #ifdef BOOST_TEST_USE_ALT_STACK
0724 if( alt_stack )
0725 m_new_action.sa_flags |= SA_ONSTACK;
0726 #endif
0727
0728 BOOST_TEST_SYS_ASSERT( ::sigaction( m_sig, &m_new_action, &m_old_action ) != -1 );
0729 }
0730
0731
0732
0733 signal_action::~signal_action()
0734 {
0735 if( m_installed )
0736 ::sigaction( m_sig, &m_old_action , sigaction_ptr() );
0737 }
0738
0739
0740
0741
0742
0743
0744
0745 class signal_handler {
0746 public:
0747
0748 explicit signal_handler( bool catch_system_errors,
0749 bool detect_fpe,
0750 unsigned long int timeout_microseconds,
0751 bool attach_dbg,
0752 char* alt_stack );
0753
0754
0755 ~signal_handler();
0756
0757
0758 static sigjmp_buf& jump_buffer()
0759 {
0760 assert( !!s_active_handler );
0761
0762 return s_active_handler->m_sigjmp_buf;
0763 }
0764
0765 static system_signal_exception& sys_sig()
0766 {
0767 assert( !!s_active_handler );
0768
0769 return s_active_handler->m_sys_sig;
0770 }
0771
0772 private:
0773
0774 signal_handler* m_prev_handler;
0775 unsigned long int m_timeout_microseconds;
0776
0777
0778 signal_action m_ILL_action;
0779 signal_action m_FPE_action;
0780 signal_action m_SEGV_action;
0781 signal_action m_BUS_action;
0782 signal_action m_CHLD_action;
0783 signal_action m_POLL_action;
0784 signal_action m_ABRT_action;
0785 signal_action m_ALRM_action;
0786
0787 sigjmp_buf m_sigjmp_buf;
0788 system_signal_exception m_sys_sig;
0789
0790 static signal_handler* s_active_handler;
0791 };
0792
0793
0794 typedef signal_handler* signal_handler_ptr;
0795 signal_handler* signal_handler::s_active_handler = signal_handler_ptr();
0796
0797
0798
0799 signal_handler::signal_handler( bool catch_system_errors,
0800 bool detect_fpe,
0801 unsigned long int timeout_microseconds,
0802 bool attach_dbg,
0803 char* alt_stack )
0804 : m_prev_handler( s_active_handler )
0805 , m_timeout_microseconds( timeout_microseconds )
0806 , m_ILL_action ( SIGILL , catch_system_errors, attach_dbg, alt_stack )
0807 , m_FPE_action ( SIGFPE , detect_fpe , attach_dbg, alt_stack )
0808 , m_SEGV_action( SIGSEGV, catch_system_errors, attach_dbg, alt_stack )
0809 , m_BUS_action ( SIGBUS , catch_system_errors, attach_dbg, alt_stack )
0810 #ifdef BOOST_TEST_CATCH_SIGPOLL
0811 , m_POLL_action( SIGPOLL, catch_system_errors, attach_dbg, alt_stack )
0812 #endif
0813 , m_ABRT_action( SIGABRT, catch_system_errors, attach_dbg, alt_stack )
0814 , m_ALRM_action( SIGALRM, timeout_microseconds > 0, attach_dbg, alt_stack )
0815 {
0816 s_active_handler = this;
0817
0818 if( m_timeout_microseconds > 0 ) {
0819 ::alarm( 0 );
0820 ::alarm( static_cast<unsigned int>(std::ceil(timeout_microseconds / 1E6) ));
0821 }
0822
0823 #ifdef BOOST_TEST_USE_ALT_STACK
0824 if( alt_stack ) {
0825 stack_t sigstk;
0826 std::memset( &sigstk, 0, sizeof(stack_t) );
0827
0828 BOOST_TEST_SYS_ASSERT( ::sigaltstack( 0, &sigstk ) != -1 );
0829
0830 if( sigstk.ss_flags & SS_DISABLE ) {
0831 sigstk.ss_sp = alt_stack;
0832 sigstk.ss_size = BOOST_TEST_ALT_STACK_SIZE;
0833 sigstk.ss_flags = 0;
0834 BOOST_TEST_SYS_ASSERT( ::sigaltstack( &sigstk, 0 ) != -1 );
0835 }
0836 }
0837 #endif
0838 }
0839
0840
0841
0842 signal_handler::~signal_handler()
0843 {
0844 assert( s_active_handler == this );
0845
0846 if( m_timeout_microseconds > 0 )
0847 ::alarm( 0 );
0848
0849 #ifdef BOOST_TEST_USE_ALT_STACK
0850 #ifdef __GNUC__
0851
0852
0853
0854 stack_t sigstk = { 0, 0, 0 };
0855 #else
0856 stack_t sigstk = { };
0857 #endif
0858
0859 sigstk.ss_size = MINSIGSTKSZ;
0860 sigstk.ss_flags = SS_DISABLE;
0861 if( ::sigaltstack( &sigstk, 0 ) == -1 ) {
0862 int error_n = errno;
0863 std::cerr << "******** errors disabling the alternate stack:" << std::endl
0864 << "\t#error:" << error_n << std::endl
0865 << "\t" << std::strerror( error_n ) << std::endl;
0866 }
0867 #endif
0868
0869 s_active_handler = m_prev_handler;
0870 }
0871
0872
0873
0874
0875
0876
0877
0878 extern "C" {
0879
0880 static void boost_execution_monitor_jumping_signal_handler( int sig, siginfo_t* info, void* context )
0881 {
0882 signal_handler::sys_sig()( info, context );
0883
0884 siglongjmp( signal_handler::jump_buffer(), sig );
0885 }
0886
0887
0888
0889 static void boost_execution_monitor_attaching_signal_handler( int sig, siginfo_t* info, void* context )
0890 {
0891 if( !debug::attach_debugger( false ) )
0892 boost_execution_monitor_jumping_signal_handler( sig, info, context );
0893
0894
0895 BOOST_TEST_SYS_ASSERT( ::signal( sig, SIG_DFL ) != SIG_ERR );
0896 }
0897
0898
0899
0900 }
0901
0902 }
0903
0904
0905
0906
0907
0908 int
0909 execution_monitor::catch_signals( boost::function<int ()> const& F )
0910 {
0911 using namespace detail;
0912
0913 #if defined(__CYGWIN__)
0914 p_catch_system_errors.value = false;
0915 #endif
0916
0917 #ifdef BOOST_TEST_USE_ALT_STACK
0918 if( !!p_use_alt_stack && !m_alt_stack )
0919 m_alt_stack.reset( new char[BOOST_TEST_ALT_STACK_SIZE] );
0920 #else
0921 p_use_alt_stack.value = false;
0922 #endif
0923
0924 signal_handler local_signal_handler( p_catch_system_errors,
0925 p_catch_system_errors || (p_detect_fp_exceptions != fpe::BOOST_FPE_OFF),
0926 p_timeout,
0927 p_auto_start_dbg,
0928 !p_use_alt_stack ? 0 : m_alt_stack.get() );
0929
0930 if( !sigsetjmp( signal_handler::jump_buffer(), 1 ) )
0931 return detail::do_invoke( m_custom_translators , F );
0932 else
0933 BOOST_TEST_I_THROW( local_signal_handler.sys_sig() );
0934 }
0935
0936
0937
0938 #elif defined(BOOST_SEH_BASED_SIGNAL_HANDLING)
0939
0940
0941
0942
0943
0944 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0564))
0945 namespace { void _set_se_translator( void* ) {} }
0946 #endif
0947
0948 namespace detail {
0949
0950
0951
0952
0953
0954 class system_signal_exception {
0955 public:
0956
0957 explicit system_signal_exception( execution_monitor* em )
0958 : m_em( em )
0959 , m_se_id( 0 )
0960 , m_fault_address( 0 )
0961 , m_dir( false )
0962 , m_timeout( false )
0963 {}
0964
0965 void set_timed_out();
0966 void report() const;
0967 int operator()( unsigned id, _EXCEPTION_POINTERS* exps );
0968
0969 private:
0970
0971 execution_monitor* m_em;
0972
0973 unsigned m_se_id;
0974 void* m_fault_address;
0975 bool m_dir;
0976 bool m_timeout;
0977 };
0978
0979
0980
0981 #if BOOST_WORKAROUND( BOOST_MSVC, <= 1310)
0982 static void
0983 seh_catch_preventer( unsigned , _EXCEPTION_POINTERS* )
0984 {
0985 throw;
0986 }
0987 #endif
0988
0989
0990
0991 void
0992 system_signal_exception::set_timed_out()
0993 {
0994 m_timeout = true;
0995 }
0996
0997
0998
0999 int
1000 system_signal_exception::operator()( unsigned id, _EXCEPTION_POINTERS* exps )
1001 {
1002 const unsigned MSFT_CPP_EXCEPT = 0xE06d7363;
1003
1004
1005 if( id == MSFT_CPP_EXCEPT )
1006 return EXCEPTION_CONTINUE_SEARCH;
1007
1008
1009 if( !m_em->p_catch_system_errors ) {
1010 if( !m_em->p_detect_fp_exceptions )
1011 return EXCEPTION_CONTINUE_SEARCH;
1012
1013 switch( id ) {
1014 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
1015 case EXCEPTION_FLT_STACK_CHECK:
1016 case EXCEPTION_FLT_DENORMAL_OPERAND:
1017 case EXCEPTION_FLT_INEXACT_RESULT:
1018 case EXCEPTION_FLT_OVERFLOW:
1019 case EXCEPTION_FLT_UNDERFLOW:
1020 case EXCEPTION_FLT_INVALID_OPERATION:
1021 case STATUS_FLOAT_MULTIPLE_FAULTS:
1022 case STATUS_FLOAT_MULTIPLE_TRAPS:
1023 break;
1024 default:
1025 return EXCEPTION_CONTINUE_SEARCH;
1026 }
1027 }
1028
1029 if( !!m_em->p_auto_start_dbg && debug::attach_debugger( false ) ) {
1030 m_em->p_catch_system_errors.value = false;
1031 #if BOOST_WORKAROUND( BOOST_MSVC, <= 1310)
1032 _set_se_translator( &seh_catch_preventer );
1033 #endif
1034 return EXCEPTION_CONTINUE_EXECUTION;
1035 }
1036
1037 m_se_id = id;
1038 if( m_se_id == EXCEPTION_ACCESS_VIOLATION && exps->ExceptionRecord->NumberParameters == 2 ) {
1039 m_fault_address = (void*)exps->ExceptionRecord->ExceptionInformation[1];
1040 m_dir = exps->ExceptionRecord->ExceptionInformation[0] == 0;
1041 }
1042
1043 return EXCEPTION_EXECUTE_HANDLER;
1044 }
1045
1046
1047
1048 void
1049 system_signal_exception::report() const
1050 {
1051 switch( m_se_id ) {
1052
1053 case EXCEPTION_ACCESS_VIOLATION: {
1054 if( !m_fault_address )
1055 detail::report_error( execution_exception::system_fatal_error, "memory access violation" );
1056 else
1057 detail::report_error(
1058 execution_exception::system_fatal_error,
1059 "memory access violation occurred at address 0x%" BOOST_TEST_PRIxPTR ", while attempting to %s",
1060 m_fault_address,
1061 m_dir ? " read inaccessible data"
1062 : " write to an inaccessible (or protected) address"
1063 );
1064 break;
1065 }
1066
1067 case EXCEPTION_ILLEGAL_INSTRUCTION:
1068 detail::report_error( execution_exception::system_fatal_error, "illegal instruction" );
1069 break;
1070
1071 case EXCEPTION_PRIV_INSTRUCTION:
1072 detail::report_error( execution_exception::system_fatal_error, "tried to execute an instruction whose operation is not allowed in the current machine mode" );
1073 break;
1074
1075 case EXCEPTION_IN_PAGE_ERROR:
1076 detail::report_error( execution_exception::system_fatal_error, "access to a memory page that is not present" );
1077 break;
1078
1079 case EXCEPTION_STACK_OVERFLOW:
1080 detail::report_error( execution_exception::system_fatal_error, "stack overflow" );
1081 break;
1082
1083 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1084 detail::report_error( execution_exception::system_fatal_error, "tried to continue execution after a non continuable exception occurred" );
1085 break;
1086
1087
1088 case EXCEPTION_DATATYPE_MISALIGNMENT:
1089 detail::report_error( execution_exception::system_error, "data misalignment" );
1090 break;
1091
1092 case EXCEPTION_INT_DIVIDE_BY_ZERO:
1093 detail::report_error( execution_exception::system_error, "integer divide by zero" );
1094 break;
1095
1096 case EXCEPTION_INT_OVERFLOW:
1097 detail::report_error( execution_exception::system_error, "integer overflow" );
1098 break;
1099
1100 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1101 detail::report_error( execution_exception::system_error, "array bounds exceeded" );
1102 break;
1103
1104 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
1105 detail::report_error( execution_exception::system_error, "floating point divide by zero" );
1106 break;
1107
1108 case EXCEPTION_FLT_STACK_CHECK:
1109 detail::report_error( execution_exception::system_error,
1110 "stack overflowed or underflowed as the result of a floating-point operation" );
1111 break;
1112
1113 case EXCEPTION_FLT_DENORMAL_OPERAND:
1114 detail::report_error( execution_exception::system_error,
1115 "operand of floating point operation is denormal" );
1116 break;
1117
1118 case EXCEPTION_FLT_INEXACT_RESULT:
1119 detail::report_error( execution_exception::system_error,
1120 "result of a floating-point operation cannot be represented exactly" );
1121 break;
1122
1123 case EXCEPTION_FLT_OVERFLOW:
1124 detail::report_error( execution_exception::system_error,
1125 "exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type" );
1126 break;
1127
1128 case EXCEPTION_FLT_UNDERFLOW:
1129 detail::report_error( execution_exception::system_error,
1130 "exponent of a floating-point operation is less than the magnitude allowed by the corresponding type" );
1131 break;
1132
1133 case EXCEPTION_FLT_INVALID_OPERATION:
1134 detail::report_error( execution_exception::system_error, "floating point error" );
1135 break;
1136
1137 case STATUS_FLOAT_MULTIPLE_FAULTS:
1138 detail::report_error( execution_exception::system_error, "multiple floating point errors" );
1139 break;
1140
1141 case STATUS_FLOAT_MULTIPLE_TRAPS:
1142 detail::report_error( execution_exception::system_error, "multiple floating point errors" );
1143 break;
1144
1145 case EXCEPTION_BREAKPOINT:
1146 detail::report_error( execution_exception::system_error, "breakpoint encountered" );
1147 break;
1148
1149 default:
1150 if( m_timeout ) {
1151 detail::report_error(execution_exception::timeout_error, "timeout while executing function");
1152 }
1153 else {
1154 detail::report_error( execution_exception::system_error, "unrecognized exception. Id: 0x%" BOOST_TEST_PRIxPTR, m_se_id );
1155 }
1156 break;
1157 }
1158 }
1159
1160
1161
1162
1163
1164
1165
1166 int BOOST_TEST_CALL_DECL
1167 assert_reporting_function( int reportType, char* userMessage, int* )
1168 {
1169
1170 if( reportType == BOOST_TEST_CRT_ASSERT || reportType == BOOST_TEST_CRT_ERROR )
1171 detail::report_error( reportType == BOOST_TEST_CRT_ASSERT ? execution_exception::user_error : execution_exception::system_error, userMessage );
1172
1173 return 0;
1174 }
1175
1176
1177
1178 void BOOST_TEST_CALL_DECL
1179 invalid_param_handler( wchar_t const* ,
1180 wchar_t const* ,
1181 wchar_t const* ,
1182 unsigned ,
1183 uintptr_t )
1184 {
1185 detail::report_error( execution_exception::user_error,
1186 "Invalid parameter detected by C runtime library" );
1187 }
1188
1189
1190
1191 }
1192
1193
1194
1195
1196
1197 int
1198 execution_monitor::catch_signals( boost::function<int ()> const& F )
1199 {
1200 _invalid_parameter_handler old_iph = _invalid_parameter_handler();
1201 BOOST_TEST_CRT_HOOK_TYPE old_crt_hook = 0;
1202
1203 if( p_catch_system_errors ) {
1204 old_crt_hook = BOOST_TEST_CRT_SET_HOOK( &detail::assert_reporting_function );
1205
1206 old_iph = _set_invalid_parameter_handler(
1207 reinterpret_cast<_invalid_parameter_handler>( &detail::invalid_param_handler ) );
1208 } else if( !p_detect_fp_exceptions ) {
1209 #if BOOST_WORKAROUND( BOOST_MSVC, <= 1310)
1210 _set_se_translator( &detail::seh_catch_preventer );
1211 #endif
1212 }
1213
1214 #if defined(BOOST_TEST_WIN32_WAITABLE_TIMERS)
1215 HANDLE htimer = INVALID_HANDLE_VALUE;
1216 BOOL bTimerSuccess = FALSE;
1217
1218 if( p_timeout ) {
1219 htimer = ::CreateWaitableTimer(
1220 NULL,
1221 TRUE,
1222 NULL);
1223
1224 if( htimer != INVALID_HANDLE_VALUE ) {
1225 LARGE_INTEGER liDueTime;
1226 liDueTime.QuadPart = - static_cast<LONGLONG>(p_timeout) * 10ll;
1227
1228 bTimerSuccess = ::SetWaitableTimer(
1229 htimer,
1230 &liDueTime,
1231 0,
1232 0,
1233 0,
1234 FALSE);
1235 }
1236 }
1237 #endif
1238
1239 detail::system_signal_exception SSE( this );
1240
1241 int ret_val = 0;
1242
1243 bool l_catch_system_errors = p_catch_system_errors;
1244
1245 __try {
1246 __try {
1247 ret_val = detail::do_invoke( m_custom_translators, F );
1248 }
1249 __except( SSE( GetExceptionCode(), GetExceptionInformation() ) ) {
1250 throw SSE;
1251 }
1252
1253
1254
1255
1256 if( bTimerSuccess && htimer != INVALID_HANDLE_VALUE) {
1257 if (::WaitForSingleObject(htimer, 0) == WAIT_OBJECT_0) {
1258 SSE.set_timed_out();
1259 throw SSE;
1260 }
1261 }
1262
1263 }
1264 __finally {
1265
1266 #if defined(BOOST_TEST_WIN32_WAITABLE_TIMERS)
1267 if( htimer != INVALID_HANDLE_VALUE ) {
1268 ::CloseHandle(htimer);
1269 }
1270 #endif
1271
1272 if( l_catch_system_errors ) {
1273 BOOST_TEST_CRT_SET_HOOK( old_crt_hook );
1274
1275 _set_invalid_parameter_handler( old_iph );
1276 }
1277 }
1278
1279 return ret_val;
1280 }
1281
1282
1283
1284 #else
1285
1286 namespace detail {
1287
1288 class system_signal_exception {
1289 public:
1290 void report() const {}
1291 };
1292
1293 }
1294
1295 int
1296 execution_monitor::catch_signals( boost::function<int ()> const& F )
1297 {
1298 return detail::do_invoke( m_custom_translators , F );
1299 }
1300
1301
1302
1303 #endif
1304
1305
1306
1307
1308
1309 execution_monitor::execution_monitor()
1310 : p_catch_system_errors( true )
1311 , p_auto_start_dbg( false )
1312 , p_timeout( 0 )
1313 , p_use_alt_stack( true )
1314 , p_detect_fp_exceptions( fpe::BOOST_FPE_OFF )
1315 {}
1316
1317
1318
1319 int
1320 execution_monitor::execute( boost::function<int ()> const& F )
1321 {
1322 if( debug::under_debugger() )
1323 p_catch_system_errors.value = false;
1324
1325 BOOST_TEST_I_TRY {
1326 detail::fpe_except_guard G( p_detect_fp_exceptions );
1327 boost::ignore_unused( G );
1328
1329 return catch_signals( F );
1330 }
1331
1332 #ifndef BOOST_NO_EXCEPTIONS
1333
1334
1335
1336
1337
1338
1339 catch( char const* ex )
1340 { detail::report_error( execution_exception::cpp_exception_error,
1341 "C string: %s", ex ); }
1342 catch( std::string const& ex )
1343 { detail::report_error( execution_exception::cpp_exception_error,
1344 "std::string: %s", ex.c_str() ); }
1345
1346
1347 catch( boost::exception const& ex )
1348 { detail::report_error( execution_exception::cpp_exception_error,
1349 &ex,
1350 "%s", boost::diagnostic_information(ex).c_str() ); }
1351
1352
1353 #if defined(BOOST_NO_TYPEID) || defined(BOOST_NO_RTTI)
1354 #define CATCH_AND_REPORT_STD_EXCEPTION( ex_name ) \
1355 catch( ex_name const& ex ) \
1356 { detail::report_error( execution_exception::cpp_exception_error, \
1357 current_exception_cast<boost::exception const>(), \
1358 #ex_name ": %s", ex.what() ); } \
1359
1360 #else
1361 #define CATCH_AND_REPORT_STD_EXCEPTION( ex_name ) \
1362 catch( ex_name const& ex ) \
1363 { detail::report_error( execution_exception::cpp_exception_error, \
1364 current_exception_cast<boost::exception const>(), \
1365 "%s: %s", detail::typeid_name(ex).c_str(), ex.what() ); } \
1366
1367 #endif
1368
1369 CATCH_AND_REPORT_STD_EXCEPTION( std::bad_alloc )
1370 CATCH_AND_REPORT_STD_EXCEPTION( std::bad_cast )
1371 CATCH_AND_REPORT_STD_EXCEPTION( std::bad_typeid )
1372 CATCH_AND_REPORT_STD_EXCEPTION( std::bad_exception )
1373 CATCH_AND_REPORT_STD_EXCEPTION( std::domain_error )
1374 CATCH_AND_REPORT_STD_EXCEPTION( std::invalid_argument )
1375 CATCH_AND_REPORT_STD_EXCEPTION( std::length_error )
1376 CATCH_AND_REPORT_STD_EXCEPTION( std::out_of_range )
1377 CATCH_AND_REPORT_STD_EXCEPTION( std::range_error )
1378 CATCH_AND_REPORT_STD_EXCEPTION( std::overflow_error )
1379 CATCH_AND_REPORT_STD_EXCEPTION( std::underflow_error )
1380 CATCH_AND_REPORT_STD_EXCEPTION( std::logic_error )
1381 CATCH_AND_REPORT_STD_EXCEPTION( std::runtime_error )
1382 CATCH_AND_REPORT_STD_EXCEPTION( std::exception )
1383 #undef CATCH_AND_REPORT_STD_EXCEPTION
1384
1385
1386 catch( system_error const& ex )
1387 { detail::report_error( execution_exception::cpp_exception_error,
1388 "system_error produced by: %s: %s", ex.p_failed_exp, std::strerror( ex.p_errno ) ); }
1389 catch( detail::system_signal_exception const& ex )
1390 { ex.report(); }
1391
1392
1393 catch( execution_aborted const& )
1394 { return 0; }
1395
1396
1397 catch( execution_exception const& )
1398 { throw; }
1399
1400
1401 catch( ... )
1402 { detail::report_error( execution_exception::cpp_exception_error, "unknown type" ); }
1403
1404 #endif
1405
1406 BOOST_TEST_UNREACHABLE_RETURN(0);
1407 }
1408
1409
1410
1411 namespace detail {
1412
1413 struct forward {
1414 explicit forward( boost::function<void ()> const& F ) : m_F( F ) {}
1415
1416 int operator()() { m_F(); return 0; }
1417
1418 boost::function<void ()> const& m_F;
1419 };
1420
1421 }
1422 void
1423 execution_monitor::vexecute( boost::function<void ()> const& F )
1424 {
1425 execute( detail::forward( F ) );
1426 }
1427
1428
1429
1430
1431
1432 system_error::system_error( char const* exp )
1433 #ifdef UNDER_CE
1434 : p_errno( GetLastError() )
1435 #else
1436 : p_errno( errno )
1437 #endif
1438 , p_failed_exp( exp )
1439 {}
1440
1441
1442
1443
1444
1445
1446
1447 execution_exception::execution_exception( error_code ec_, const_string what_msg_, location const& location_ )
1448 : m_error_code( ec_ )
1449 , m_what( what_msg_.empty() ? BOOST_TEST_L( "uncaught exception, system error or abort requested" ) : what_msg_ )
1450 , m_location( location_ )
1451 {}
1452
1453
1454
1455 execution_exception::location::location( char const* file_name, size_t line_num, char const* func )
1456 : m_file_name( file_name ? file_name : "unknown location" )
1457 , m_line_num( line_num )
1458 , m_function( func )
1459 {}
1460
1461 execution_exception::location::location(const_string file_name, size_t line_num, char const* func )
1462 : m_file_name( file_name )
1463 , m_line_num( line_num )
1464 , m_function( func )
1465 {}
1466
1467
1468
1469
1470
1471
1472
1473 namespace fpe {
1474
1475 unsigned
1476 enable( unsigned mask )
1477 {
1478 boost::ignore_unused(mask);
1479 #if defined(BOOST_TEST_FPE_SUPPORT_WITH_SEH__)
1480 _clearfp();
1481
1482 #if BOOST_WORKAROUND( BOOST_MSVC, <= 1310)
1483 unsigned old_cw = ::_controlfp( 0, 0 );
1484 ::_controlfp( old_cw & ~mask, BOOST_FPE_ALL );
1485 #else
1486 unsigned old_cw;
1487 if( ::_controlfp_s( &old_cw, 0, 0 ) != 0 )
1488 return BOOST_FPE_INV;
1489
1490
1491 if( ::_controlfp_s( 0, old_cw & ~mask, BOOST_FPE_ALL ) != 0 )
1492 return BOOST_FPE_INV;
1493 #endif
1494 return ~old_cw & BOOST_FPE_ALL;
1495
1496 #elif defined(BOOST_TEST_FPE_SUPPORT_WITH_GLIBC_EXTENSIONS__)
1497
1498 if (BOOST_FPE_ALL == BOOST_FPE_OFF)
1499
1500 return BOOST_FPE_OFF;
1501 feclearexcept(BOOST_FPE_ALL);
1502 int res = feenableexcept( mask );
1503 return res == -1 ? (unsigned)BOOST_FPE_INV : (unsigned)res;
1504 #else
1505
1506 return BOOST_FPE_OFF;
1507 #endif
1508 }
1509
1510
1511
1512 unsigned
1513 disable( unsigned mask )
1514 {
1515 boost::ignore_unused(mask);
1516
1517 #if defined(BOOST_TEST_FPE_SUPPORT_WITH_SEH__)
1518 _clearfp();
1519 #if BOOST_WORKAROUND( BOOST_MSVC, <= 1310)
1520 unsigned old_cw = ::_controlfp( 0, 0 );
1521 ::_controlfp( old_cw | mask, BOOST_FPE_ALL );
1522 #else
1523 unsigned old_cw;
1524 if( ::_controlfp_s( &old_cw, 0, 0 ) != 0 )
1525 return BOOST_FPE_INV;
1526
1527
1528 if( ::_controlfp_s( 0, old_cw | mask, BOOST_FPE_ALL ) != 0 )
1529 return BOOST_FPE_INV;
1530 #endif
1531 return ~old_cw & BOOST_FPE_ALL;
1532
1533 #elif defined(BOOST_TEST_FPE_SUPPORT_WITH_GLIBC_EXTENSIONS__)
1534 if (BOOST_FPE_ALL == BOOST_FPE_OFF)
1535
1536 return BOOST_FPE_INV;
1537 feclearexcept(BOOST_FPE_ALL);
1538 int res = fedisableexcept( mask );
1539 return res == -1 ? (unsigned)BOOST_FPE_INV : (unsigned)res;
1540 #else
1541
1542 return BOOST_FPE_INV;
1543 #endif
1544 }
1545
1546
1547
1548 }
1549
1550 }
1551
1552 #include <boost/test/detail/enable_warnings.hpp>
1553
1554 #endif