execution_monitor.ipp 52 KB

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