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