execution_monitor.ipp 48 KB

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