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