execution_monitor.ipp 53 KB

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