|
Boost-Commit : |
From: eric_at_[hidden]
Date: 2007-10-16 15:07:13
Author: eric_niebler
Date: 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
New Revision: 40094
URL: http://svn.boost.org/trac/boost/changeset/40094
Log:
reverted to r40064
Text files modified:
trunk/boost/test/execution_monitor.hpp | 52 -
trunk/boost/test/framework.hpp | 12
trunk/boost/test/impl/cpp_main.ipp | 9
trunk/boost/test/impl/execution_monitor.ipp | 1191 +++++++++++++--------------------------
trunk/boost/test/impl/framework.ipp | 97 ++-
trunk/boost/test/impl/results_reporter.ipp | 4
trunk/boost/test/impl/unit_test_log.ipp | 3
trunk/boost/test/impl/unit_test_main.ipp | 26
trunk/boost/test/impl/unit_test_monitor.ipp | 9
trunk/boost/test/impl/unit_test_suite.ipp | 6
trunk/boost/test/interaction_based.hpp | 4
trunk/boost/test/unit_test.hpp | 10
trunk/boost/test/unit_test_suite_impl.hpp | 7
13 files changed, 522 insertions(+), 908 deletions(-)
Modified: trunk/boost/test/execution_monitor.hpp
==============================================================================
--- trunk/boost/test/execution_monitor.hpp (original)
+++ trunk/boost/test/execution_monitor.hpp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -36,11 +36,9 @@
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/utils/callback.hpp>
-#include <boost/test/utils/class_properties.hpp>
// Boost
#include <boost/scoped_ptr.hpp>
-#include <boost/scoped_array.hpp>
#include <boost/type.hpp>
#include <boost/cstdlib.hpp>
@@ -133,32 +131,14 @@
class BOOST_TEST_DECL execution_monitor {
public:
- // Constructor
- execution_monitor()
- : p_catch_system_errors( true )
- , p_auto_start_dbg( false )
- , p_timeout( 0 )
- {}
-
- // Public properties
-
- // The p_catch_system_errors parameter specifies whether the monitor should
+ int execute( unit_test::callback0<int> const& F, bool catch_system_errors = true, int timeout = 0 );
+ // The catch_system_errors parameter specifies whether the monitor should
// try to catch system errors/exceptions that would cause program to crash
// in regular case
- unit_test::readwrite_property<bool> p_catch_system_errors;
- // The p_auto_start_dbg parameter specifies whether the monitor should
- // try to attach debugger in case of caught system error
- unit_test::readwrite_property<bool> p_auto_start_dbg;
- // The p_timeout parameter specifies the seconds that elapse before
+ // The timeout argument specifies the seconds that elapse before
// a timer_error occurs. May be ignored on some platforms.
- unit_test::readwrite_property<int> p_timeout;
- // The p_use_alt_stack parameter specifies whether the monitor should
- // use alternative stack for the signal catching
- unit_test::readwrite_property<int> p_use_alt_stack;
-
-
- int execute( unit_test::callback0<int> const& F );
- // Returns: Value returned by function call F().
+ //
+ // Returns: Value returned by function().
//
// Effects: Calls executes supplied function F inside a try/catch block which also may
// include other unspecified platform dependent error detection code.
@@ -174,11 +154,10 @@
private:
// implementation helpers
- int catch_signals( unit_test::callback0<int> const& F );
+ int catch_signals( unit_test::callback0<int> const& F, bool catch_system_errors, int timeout );
// Data members
boost::scoped_ptr<detail::translate_exception_base> m_custom_translators;
- boost::scoped_array<char> m_alt_stack;
}; // execution_monitor
namespace detail {
@@ -221,24 +200,19 @@
}
// ************************************************************************** //
-// ************** execution_aborted ************** //
+// ************** detect_memory_leaks ************** //
// ************************************************************************** //
-struct execution_aborted {};
+// turn on system memory leak detection
+void BOOST_TEST_DECL detect_memory_leaks( bool on_off );
+// break program execution on mem_alloc_order_num's allocation
+void BOOST_TEST_DECL break_memory_alloc( long mem_alloc_order_num );
// ************************************************************************** //
-// ************** system_error ************** //
+// ************** execution_aborted ************** //
// ************************************************************************** //
-class system_error {
-public:
- // Constructor
- system_error();
-
- unit_test::readonly_property<long> p_errno;
-};
-
-#define BOOST_TEST_SYS_ASSERT( exp ) if( (exp) ) ; else throw ::boost::system_error()
+struct BOOST_TEST_DECL execution_aborted {};
} // namespace boost
Modified: trunk/boost/test/framework.hpp
==============================================================================
--- trunk/boost/test/framework.hpp (original)
+++ trunk/boost/test/framework.hpp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -32,23 +32,13 @@
namespace unit_test {
// ************************************************************************** //
-// ************** init_unit_test_func ************** //
-// ************************************************************************** //
-
-#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
-typedef bool (*init_unit_test_func)();
-#else
-typedef test_suite* (*init_unit_test_func)( int, char* [] );
-#endif
-
-// ************************************************************************** //
// ************** framework ************** //
// ************************************************************************** //
namespace framework {
// initialization
-BOOST_TEST_DECL void init( init_unit_test_func init_func, int argc, char* argv[] );
+BOOST_TEST_DECL void init( int argc, char* argv[] );
// mutation access methods
BOOST_TEST_DECL void register_test_unit( test_case* tc );
Modified: trunk/boost/test/impl/cpp_main.ipp
==============================================================================
--- trunk/boost/test/impl/cpp_main.ipp (original)
+++ trunk/boost/test/impl/cpp_main.ipp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -69,14 +69,13 @@
{
int result = 0;
+ boost::unit_test::const_string p( std::getenv( "BOOST_TEST_CATCH_SYSTEM_ERRORS" ) );
+ bool catch_system_errors = p != "no";
+
try {
- boost::unit_test::const_string p( std::getenv( "BOOST_TEST_CATCH_SYSTEM_ERRORS" ) );
::boost::execution_monitor ex_mon;
-
- ex_mon.p_catch_system_errors.value = p != "no";
-
result = ex_mon.execute(
- ::boost::unit_test::callback0<int>( cpp_main_caller( cpp_main, argc, argv ) ) );
+ ::boost::unit_test::callback0<int>( cpp_main_caller( cpp_main, argc, argv ) ), catch_system_errors );
if( result == 0 )
result = ::boost::exit_success;
Modified: trunk/boost/test/impl/execution_monitor.ipp
==============================================================================
--- trunk/boost/test/impl/execution_monitor.ipp (original)
+++ trunk/boost/test/impl/execution_monitor.ipp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -30,63 +30,54 @@
#include <boost/test/execution_monitor.hpp>
// Boost
-#include <boost/cstdlib.hpp> // for exit codes
-#include <boost/config.hpp> // for workarounds
+#include <boost/cstdlib.hpp> // for exit codes
+#include <boost/config.hpp> // for workarounds
// STL
-#include <string> // for std::string
-#include <new> // for std::bad_alloc
-#include <typeinfo> // for std::bad_cast, std::bad_typeid
-#include <exception> // for std::exception, std::bad_exception
-#include <stdexcept> // for std exception hierarchy
-#include <cstring> // for C string API
-#include <cassert> // for assert
-#include <cstddef> // for NULL
-#include <cstdio> // for vsnprintf
-#include <cstdarg> // for varargs
+#include <string> // for std::string
+#include <new> // for std::bad_alloc
+#include <typeinfo> // for std::bad_cast, std::bad_typeid
+#include <exception> // for std::exception, std::bad_exception
+#include <stdexcept> // for std exception hierarchy
+#include <cstring> // for C string API
+#include <cassert> // for assert
+#include <cstddef> // for NULL
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::strlen; using ::strncat; }
#endif
-#if defined(_WIN32) && !defined(BOOST_DISABLE_WIN32) && \
- (!defined(__COMO__) && !defined(__MWERKS__) && !defined(__GNUC__) || \
- BOOST_WORKAROUND(__MWERKS__, >= 0x3000))
-
-# define BOOST_SEH_BASED_SIGNAL_HANDLING
-
-# include <windows.h>
-# if defined(__MWERKS__)
-# include <eh.h>
-
-typedef void* uintptr_t;
+// Microsoft + other compatible compilers such as Intel
+#if !defined(BOOST_DISABLE_WIN32) && \
+ !defined(__BORLANDC__) && \
+ (defined(_MSC_VER) && !defined(__COMO__)) || \
+ (BOOST_WORKAROUND(__MWERKS__, >= 0x3000) && defined(__INTEL__))
+
+# define BOOST_MS_STRUCTURED_EXCEPTION_HANDLING
+
+# ifndef _WIN32_WINNT
+# ifdef _WINBASE_
+# pragma message("Warning: Debugger check disabled. Either define _WIN32_WINNT or include Boost.Test header in front of winbase.h")
+# else
+# define BOOST_TEST_DEBUGGER_CHECK
+# define _WIN32_WINNT 0x0400
+# endif
# endif
-// for the FP control routines
-#include <float.h>
+# include <wtypes.h>
+# include <winbase.h>
+# include <excpt.h>
+# include <eh.h>
-# if !defined(NDEBUG) && defined(_MSC_VER)
-# define BOOST_TEST_USE_DEBUG_MS_CRT
+# if !defined(NDEBUG) && !defined(__MWERKS__) // __MWERKS__ does not seem to supply implementation of C runtime debug hooks, causing linking errors
+# define BOOST_MS_CRT_DEBUG_HOOKS
# include <crtdbg.h>
# endif
-# if !BOOST_WORKAROUND(BOOST_MSVC, >= 1400 )
-
-typedef void* _invalid_parameter_handler;
-
-inline _invalid_parameter_handler
-_set_invalid_parameter_handler( _invalid_parameter_handler arg )
-{
- return arg;
-}
-
-# endif
-
-# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
+#elif (defined(__BORLANDC__) && defined(_Windows) && !defined(BOOST_DISABLE_WIN32))
-namespace { void _set_se_translator( void* ) {} }
-
-# endif
+# define BOOST_MS_STRUCTURED_EXCEPTION_HANDLING
+# include <windows.h> // Borland 5.5.1 has its own way of doing things.
#elif defined(BOOST_HAS_SIGACTION)
@@ -96,431 +87,228 @@
# include <signal.h>
# include <setjmp.h>
-# if !defined(__CYGWIN__)
-# define BOOST_TEST_USE_ALT_STACK
-# endif
-
-# ifdef BOOST_TEST_USE_ALT_STACK
-# define BOOST_TEST_ALT_STACK_SIZE SIGSTKSZ
-# endif
-
#else
# define BOOST_NO_SIGNAL_HANDLING
#endif
-#include <errno.h>
-
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
-// ************************************************************************** //
-// ************** report_error ************** //
-// ************************************************************************** //
-
namespace detail {
-#ifdef __BORLANDC__
-# define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) std::vsnprintf( (a1), (a2), (a3), (a4) )
-#elif BOOST_WORKAROUND(_MSC_VER, <= 1310) || \
- BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3000))
-# define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) _vsnprintf( (a1), (a2), (a3), (a4) )
-#else
-# define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) vsnprintf( (a1), (a2), (a3), (a4) )
-#endif
-
-static void
-report_error( execution_exception::error_code ec, char const* format, ... )
-{
- static const int REPORT_ERROR_BUFFER_SIZE = 512;
- static char buf[REPORT_ERROR_BUFFER_SIZE];
+using unit_test::const_string;
- va_list args;
- va_start( args, format );
+// boost::execution_monitor::execute() calls boost::detail::report_error(...) to
+// report any caught exception and throw execution_exception
- BOOST_TEST_VSNPRINTF( buf, sizeof(buf), format, args );
- va_end( args );
+const std::size_t REPORT_ERROR_BUFFER_SIZE = 512;
- throw execution_exception( ec, buf );
-}
+static void report_error(
+ execution_exception::error_code ec,
+ const_string msg1, // first part of the message
+ const_string msg2 = "" ); // second part of the message; sum length msg1 + msg2 should not
+ // exceed REPORT_ERROR_BUFFER_SIZE; never concatenate messages
+ // manually, cause it should work even in case of memory lack
//____________________________________________________________________________//
-template<typename Tr,typename Functor>
-inline int
-do_invoke( Tr const& tr, Functor const& F )
-{
- return tr ? (*tr)( F ) : F();
-}
+// Declaration for Microsoft structured exception handling (unix alternative - signal)
+#ifdef BOOST_MS_STRUCTURED_EXCEPTION_HANDLING
-//____________________________________________________________________________//
+// this class defined per the Microsoft structured exception documentation
+class ms_se_exception {
+public:
+ // Constructor
+ explicit ms_se_exception( unsigned int n )
+ : m_se_id( n ) {}
-} // namespace detail
+ // Destructor
+ ~ms_se_exception() {}
-#if defined(BOOST_SIGACTION_BASED_SIGNAL_HANDLING)
+ // access methods
+ unsigned int id() const { return m_se_id; }
-// ************************************************************************** //
-// ************** Sigaction based signal handling ************** //
-// ************************************************************************** //
+private:
+ // Data members
+ unsigned int m_se_id;
+};
-namespace detail {
+//____________________________________________________________________________//
-// ************************************************************************** //
-// ************** boost::detail::system_signal_exception ************** //
-// ************************************************************************** //
+void BOOST_TEST_CALL_DECL ms_se_trans_func( unsigned int id, _EXCEPTION_POINTERS* exps );
+void BOOST_TEST_CALL_DECL ms_se_forward_func( unsigned int id, _EXCEPTION_POINTERS* exps );
+static void report_ms_se_error( unsigned int id );
+
+//____________________________________________________________________________//
-class system_signal_exception {
+// Declarations for unix-style signal handling
+#elif defined(BOOST_SIGACTION_BASED_SIGNAL_HANDLING)
+
+class unix_signal_exception {
+ typedef execution_exception::error_code error_code_type;
public:
// Constructor
- system_signal_exception()
- : m_sig_info( 0 )
- , m_context( 0 )
- {}
+ unix_signal_exception( execution_exception::error_code ec, const_string em )
+ : m_error_code( ec ), m_error_message( em ) {}
- // Access methods
- void operator()( siginfo_t* i, void* c )
- {
- m_sig_info = i;
- m_context = c;
- }
- void report() const;
+ // Destructor
+ ~unix_signal_exception() {}
+ // access methods
+ error_code_type error_code() const { return m_error_code; }
+ const_string error_message() const { return m_error_message; }
private:
// Data members
- siginfo_t* m_sig_info; // system signal detailed info
- void* m_context; // signal context
+ error_code_type m_error_code;
+ const_string m_error_message;
};
+#endif
+
//____________________________________________________________________________//
-void
-system_signal_exception::report() const
-{
- if( !m_sig_info )
- return; // no error actually occur?
+#if defined(BOOST_MS_CRT_DEBUG_HOOKS)
- if( m_sig_info->si_code <= 0 ) {
- switch( m_sig_info->si_code ) {
- case SI_USER:
- report_error( execution_exception::system_error,
- "signal: generated by kill() (or family); uid=%d; pid=%d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid );
- break;
- case SI_QUEUE:
- report_error( execution_exception::system_error,
- "signal: sent by sigqueue()" );
- break;
- case SI_TIMER:
- report_error( execution_exception::system_error,
- "signal: the expiration of a timer set by timer_settimer()" );
- break;
- case SI_ASYNCIO:
- report_error( execution_exception::system_error,
- "signal: generated by the completion of an asynchronous I/O request" );
- break;
- case SI_MESGQ:
- report_error( execution_exception::system_error,
- "signal: generated by the the arrival of a message on an empty message queue" );
- break;
- }
- }
- else {
- switch( m_sig_info->si_signo ) {
- case SIGILL:
- switch( m_sig_info->si_code ) {
- case ILL_ILLOPC:
- report_error( execution_exception::system_fatal_error,
- "signal: illegal opcode; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case ILL_ILLOPN:
- report_error( execution_exception::system_fatal_error,
- "signal: illegal operand; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case ILL_ILLADR:
- report_error( execution_exception::system_fatal_error,
- "signal: illegal addressing mode; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case ILL_ILLTRP:
- report_error( execution_exception::system_fatal_error,
- "signal: illegal trap; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case ILL_PRVOPC:
- report_error( execution_exception::system_fatal_error,
- "signal: privileged opcode; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case ILL_PRVREG:
- report_error( execution_exception::system_fatal_error,
- "signal: privileged register; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case ILL_COPROC:
- report_error( execution_exception::system_fatal_error,
- "signal: co-processor error; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case ILL_BADSTK:
- report_error( execution_exception::system_fatal_error,
- "signal: internal stack error; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- }
- break;
+int BOOST_TEST_CALL_DECL
+assert_reporting_function( int reportType, char* userMessage, int* retVal )
+{
+ switch( reportType ) {
+ case _CRT_ASSERT:
+ detail::report_error( execution_exception::user_error, userMessage );
- case SIGFPE:
- switch( m_sig_info->si_code ) {
- case FPE_INTDIV:
- report_error( execution_exception::system_error,
- "signal: integer divide by zero; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case FPE_INTOVF:
- report_error( execution_exception::system_error,
- "signal: integer overflow; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case FPE_FLTDIV:
- report_error( execution_exception::system_error,
- "signal: floating point divide by zero; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case FPE_FLTOVF:
- report_error( execution_exception::system_error,
- "signal: floating point overflow; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case FPE_FLTUND:
- report_error( execution_exception::system_error,
- "signal: floating point underflow; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case FPE_FLTRES:
- report_error( execution_exception::system_error,
- "signal: floating point inexact result; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case FPE_FLTINV:
- report_error( execution_exception::system_error,
- "signal: invalid floating point operation; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- case FPE_FLTSUB:
- report_error( execution_exception::system_error,
- "signal: subscript out of range; address of failing instruction: 0x%08lx",
- m_sig_info->si_addr );
- break;
- }
- break;
+ return 1; // return value and retVal are not important since we never reach this line
+ case _CRT_ERROR:
+ detail::report_error( execution_exception::system_error, userMessage );
- case SIGSEGV:
- switch( m_sig_info->si_code ) {
- case SEGV_MAPERR:
- report_error( execution_exception::system_fatal_error,
- "memory access violation at address: 0x%08lx: no mapping at fault address",
- m_sig_info->si_addr );
- break;
- case SEGV_ACCERR:
- report_error( execution_exception::system_fatal_error,
- "memory access violation at address: 0x%08lx: invalid permissions",
- m_sig_info->si_addr );
- break;
- }
- break;
+ return 1; // return value and retVal are not important since we never reach this line
+ default:
+ return 0; // use usual reporting method
+ }
+}
- case SIGBUS:
- switch( m_sig_info->si_code ) {
- case BUS_ADRALN:
- report_error( execution_exception::system_fatal_error,
- "memory access violation at address: 0x%08lx: invalid address alignment",
- m_sig_info->si_addr );
- break;
- case BUS_ADRERR:
- report_error( execution_exception::system_fatal_error,
- "memory access violation at address: 0x%08lx: non-existent physical address",
- m_sig_info->si_addr );
- break;
- case BUS_OBJERR:
- report_error( execution_exception::system_fatal_error,
- "memory access violation at address: 0x%08lx: object specific hardware error",
- m_sig_info->si_addr );
- break;
- }
- break;
+#endif
- case SIGCHLD:
- switch( m_sig_info->si_code ) {
- case CLD_EXITED:
- report_error( execution_exception::system_error,
- "child has exited; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
- break;
- case CLD_KILLED:
- report_error( execution_exception::system_error,
- "child was killed; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
- break;
- case CLD_DUMPED:
- report_error( execution_exception::system_error,
- "child terminated abnormally; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
- break;
- case CLD_TRAPPED:
- report_error( execution_exception::system_error,
- "traced child has trapped; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
- break;
- case CLD_STOPPED:
- report_error( execution_exception::system_error,
- "child has stopped; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
- break;
- case CLD_CONTINUED:
- report_error( execution_exception::system_error,
- "stopped child had continued; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
- break;
- }
- break;
+} // namespace detail
-#if !defined(__CYGWIN__)
+// ************************************************************************** //
+// ************** execution_monitor ************** //
+// ************************************************************************** //
- case SIGPOLL:
- switch( m_sig_info->si_code ) {
- case POLL_IN:
- report_error( execution_exception::system_error,
- "data input available; band event %d",
- (int)m_sig_info->si_band );
- break;
- case POLL_OUT:
- report_error( execution_exception::system_error,
- "output buffers available; band event %d",
- (int)m_sig_info->si_band );
- break;
- case POLL_MSG:
- report_error( execution_exception::system_error,
- "input message available; band event %d",
- (int)m_sig_info->si_band );
- break;
- case POLL_ERR:
- report_error( execution_exception::system_error,
- "i/o error; band event %d",
- (int)m_sig_info->si_band );
- break;
- case POLL_PRI:
- report_error( execution_exception::system_error,
- "high priority input available; band event %d",
- (int)m_sig_info->si_band );
- break;
- case POLL_HUP:
- report_error( execution_exception::system_error,
- "device disconnected; band event %d",
- (int)m_sig_info->si_band );
- break;
- }
- break;
+int
+execution_monitor::execute( unit_test::callback0<int> const& F, bool catch_system_errors, int timeout )
+{
+ using unit_test::const_string;
+# ifdef BOOST_TEST_DEBUGGER_CHECK
+ if( IsDebuggerPresent() )
+ catch_system_errors = false;
#endif
- case SIGABRT:
- report_error( execution_exception::system_error,
- "signal: SIGABRT (application abort requested)" );
- break;
+#if defined(BOOST_MS_STRUCTURED_EXCEPTION_HANDLING) && !defined(__BORLANDC__)
+ if( catch_system_errors )
+ _set_se_translator( detail::ms_se_trans_func );
+ else
+ _set_se_translator( detail::ms_se_forward_func );
+#endif
- case SIGALRM:
- report_error( execution_exception::timeout_error,
- "signal: SIGALRM (timeout while executing function)" );
- break;
+#ifdef BOOST_MS_CRT_DEBUG_HOOKS
+ if( catch_system_errors )
+ _CrtSetReportHook( &detail::assert_reporting_function );
+#endif
- default:
- report_error( execution_exception::system_error, "unrecognized signal" );
- }
+ try {
+ return catch_signals( F, catch_system_errors, timeout );
}
-}
-
-//____________________________________________________________________________//
-// ************************************************************************** //
-// ************** boost::detail::signal_action ************** //
-// ************************************************************************** //
+ // Catch-clause reference arguments are a bit different from function
+ // arguments (ISO 15.3 paragraphs 18 & 19). Apparently const isn't
+ // required. Programmers ask for const anyhow, so we supply it. That's
+ // easier than answering questions about non-const usage.
-// Forward declaration
-extern "C" {
-static void execution_monitor_jumping_signal_handler( int sig, siginfo_t* info, void* context );
-static void execution_monitor_attaching_signal_handler( int sig, siginfo_t* info, void* context );
-}
+ catch( char const* ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "C string: ", ex ); }
+ catch( std::string const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::string: ", ex.c_str() ); }
-class signal_action {
- typedef struct sigaction* sigaction_ptr;
-public:
- //Constructor
- explicit signal_action( int sig, bool install, bool attach_dbg, char* alt_stack );
- ~signal_action();
+ // std:: exceptions
-private:
- // Data members
- int m_sig;
- bool m_installed;
- struct sigaction m_new_action;
- struct sigaction m_old_action;
-};
+ catch( std::bad_alloc const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::bad_alloc: ", ex.what() ); }
-//____________________________________________________________________________//
+#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
+ catch( std::bad_cast const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::bad_cast" ); }
+ catch( std::bad_typeid const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::bad_typeid" ); }
+#else
+ catch( std::bad_cast const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::bad_cast: ", ex.what() ); }
+ catch( std::bad_typeid const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::bad_typeid: ", ex.what() ); }
+#endif
-signal_action::signal_action( int sig, bool install, bool attach_dbg, char* alt_stack )
-: m_sig( sig )
-, m_installed( install )
-{
- if( !install )
- return;
+ catch( std::bad_exception const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::bad_exception: ", ex.what() ); }
+ catch( std::domain_error const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::domain_error: ", ex.what() ); }
+ catch( std::invalid_argument const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::invalid_argument: ", ex.what() ); }
+ catch( std::length_error const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::length_error: ", ex.what() ); }
+ catch( std::out_of_range const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::out_of_range: ", ex.what() ); }
+ catch( std::range_error const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::range_error: ", ex.what() ); }
+ catch( std::overflow_error const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::overflow_error: ", ex.what() ); }
+ catch( std::underflow_error const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::underflow_error: ", ex.what() ); }
+ catch( std::logic_error const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::logic_error: ", ex.what() ); }
+ catch( std::runtime_error const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::runtime_error: ", ex.what() ); }
+ catch( std::exception const& ex )
+ { detail::report_error( execution_exception::cpp_exception_error, "std::exception: ", ex.what() ); }
- std::memset( &m_new_action, 0, sizeof(struct sigaction) );
+#if defined(BOOST_MS_STRUCTURED_EXCEPTION_HANDLING)
+ catch( detail::ms_se_exception const& ex )
+ { detail::report_ms_se_error( ex.id() ); }
+#elif defined(BOOST_SIGACTION_BASED_SIGNAL_HANDLING)
+ catch( detail::unix_signal_exception const& ex )
+ { detail::report_error( ex.error_code(), ex.error_message() ); }
+#endif // BOOST_SIGACTION_BASED_SIGNAL_HANDLING
- BOOST_TEST_SYS_ASSERT( ::sigaction( m_sig , sigaction_ptr(), &m_new_action ) != -1 );
+ catch( execution_aborted const& )
+ { return 0; }
- if( m_new_action.sa_sigaction || m_new_action.sa_handler ) {
- m_installed = false;
- return;
- }
+ catch( execution_exception const& )
+ { throw; }
- m_new_action.sa_flags |= SA_SIGINFO;
- m_new_action.sa_sigaction = attach_dbg ? &execution_monitor_attaching_signal_handler
- : &execution_monitor_jumping_signal_handler;
- BOOST_TEST_SYS_ASSERT( ::sigemptyset( &m_new_action.sa_mask ) != -1 );
-
-#ifdef BOOST_TEST_USE_ALT_STACK
- if( alt_stack )
- m_new_action.sa_flags |= SA_ONSTACK;
-#endif
+ catch( ... )
+ { detail::report_error( execution_exception::cpp_exception_error, "unknown type" ); }
- BOOST_TEST_SYS_ASSERT( ::sigaction( m_sig, &m_new_action, &m_old_action ) != -1 );
-}
+ return 0; // never reached; supplied to quiet compiler warnings
+} // execute
//____________________________________________________________________________//
-signal_action::~signal_action()
-{
- if( m_installed )
- ::sigaction( m_sig, &m_old_action , sigaction_ptr() );
-}
-
-//____________________________________________________________________________//
+#if defined(BOOST_SIGACTION_BASED_SIGNAL_HANDLING)
// ************************************************************************** //
-// ************** boost::detail::signal_handler ************** //
+// ************** boost::detail::signal_handler ************** //
// ************************************************************************** //
+namespace detail {
+
class signal_handler {
public:
// Constructor
- explicit signal_handler( bool catch_system_errors, int timeout, bool attach_dbg, char* alt_stack );
+ explicit signal_handler( bool catch_system_errors, int timeout );
// Destructor
~signal_handler();
@@ -533,257 +321,234 @@
return s_active_handler->m_sigjmp_buf;
}
- static system_signal_exception& sys_sig()
- {
- assert( !!s_active_handler );
-
- return s_active_handler->m_sys_sig;
- }
-
private:
// Data members
- signal_handler* m_prev_handler;
- int m_timeout;
-
- signal_action m_ILL_action;
- signal_action m_FPE_action;
- signal_action m_SEGV_action;
- signal_action m_BUS_action;
- signal_action m_CHLD_action;
- signal_action m_POLL_action;
- signal_action m_ABRT_action;
- signal_action m_ALRM_action;
+ struct sigaction m_same_action_for_all_signals;
+ struct sigaction m_old_SIGFPE_action;
+ struct sigaction m_old_SIGTRAP_action;
+ struct sigaction m_old_SIGSEGV_action;
+ struct sigaction m_old_SIGBUS_action;
+ struct sigaction m_old_SIGABRT_action;
+ struct sigaction m_old_SIGALRM_action;
sigjmp_buf m_sigjmp_buf;
- system_signal_exception m_sys_sig;
+ signal_handler* m_prev_handler;
static signal_handler* s_active_handler;
+
+ bool m_catch_system_errors;
+ bool m_set_timeout;
};
-// !! need to be placed in thread specific storage
-typedef signal_handler* signal_handler_ptr;
-signal_handler* signal_handler::s_active_handler = signal_handler_ptr();
+signal_handler* signal_handler::s_active_handler = NULL; // !! need to be placed in thread specific storage
//____________________________________________________________________________//
-signal_handler::signal_handler( bool catch_system_errors, int timeout, bool attach_dbg, char* alt_stack )
+extern "C" {
+
+static void execution_monitor_signal_handler( int sig )
+{
+ siglongjmp( signal_handler::jump_buffer(), sig );
+}
+
+}
+
+//____________________________________________________________________________//
+
+signal_handler::signal_handler( bool catch_system_errors, int timeout )
: m_prev_handler( s_active_handler )
-, m_timeout( timeout )
-, m_ILL_action ( SIGILL , catch_system_errors, attach_dbg, alt_stack )
-, m_FPE_action ( SIGFPE , catch_system_errors, attach_dbg, alt_stack )
-, m_SEGV_action( SIGSEGV, catch_system_errors, attach_dbg, alt_stack )
-, m_BUS_action ( SIGBUS , catch_system_errors, attach_dbg, alt_stack )
-, m_CHLD_action( SIGCHLD, catch_system_errors, attach_dbg, alt_stack )
-, m_POLL_action( SIGPOLL, catch_system_errors, attach_dbg, alt_stack )
-, m_ABRT_action( SIGABRT, catch_system_errors, attach_dbg, alt_stack )
-, m_ALRM_action( SIGALRM, timeout > 0 , attach_dbg, alt_stack )
+, m_catch_system_errors( catch_system_errors )
+, m_set_timeout( timeout > 0 )
{
s_active_handler = this;
- if( m_timeout > 0 ) {
- ::alarm( 0 );
- ::alarm( timeout );
- }
-
-#ifdef BOOST_TEST_USE_ALT_STACK
- if( alt_stack ) {
- stack_t sigstk;
-
- BOOST_TEST_SYS_ASSERT( ::sigaltstack( 0, &sigstk ) != -1 );
-
- if( sigstk.ss_flags & SS_DISABLE ) {
- sigstk.ss_sp = alt_stack;
- sigstk.ss_size = BOOST_TEST_ALT_STACK_SIZE;
- sigstk.ss_flags = 0;
- BOOST_TEST_SYS_ASSERT( ::sigaltstack( &sigstk, 0 ) != -1 );
- }
+ if( m_catch_system_errors || m_set_timeout ) {
+ m_same_action_for_all_signals.sa_flags = 0;
+ m_same_action_for_all_signals.sa_handler = &execution_monitor_signal_handler;
+ sigemptyset( &m_same_action_for_all_signals.sa_mask );
+ }
+
+ if( m_catch_system_errors ) {
+ sigaction( SIGFPE , &m_same_action_for_all_signals, &m_old_SIGFPE_action );
+ sigaction( SIGTRAP, &m_same_action_for_all_signals, &m_old_SIGTRAP_action );
+ sigaction( SIGSEGV, &m_same_action_for_all_signals, &m_old_SIGSEGV_action );
+ sigaction( SIGBUS , &m_same_action_for_all_signals, &m_old_SIGBUS_action );
+ sigaction( SIGABRT, &m_same_action_for_all_signals, &m_old_SIGABRT_action );
+ }
+
+ if( m_set_timeout ) {
+ sigaction( SIGALRM , &m_same_action_for_all_signals, &m_old_SIGALRM_action );
+ alarm( timeout );
}
-#endif
}
//____________________________________________________________________________//
signal_handler::~signal_handler()
{
- assert( s_active_handler == this );
+ typedef struct sigaction* sigaction_ptr;
- if( m_timeout > 0 )
- ::alarm( 0 );
+ assert( s_active_handler == this );
-#ifdef BOOST_TEST_USE_ALT_STACK
- stack_t sigstk;
+ if( m_set_timeout ) {
+ alarm( 0 );
+ sigaction( SIGALRM, &m_old_SIGALRM_action, sigaction_ptr() );
+ }
- sigstk.ss_flags = SS_DISABLE;
- BOOST_TEST_SYS_ASSERT( ::sigaltstack( &sigstk, 0 ) != -1 );
-#endif
+ if( m_catch_system_errors ) {
+ sigaction( SIGFPE , &m_old_SIGFPE_action , sigaction_ptr() );
+ sigaction( SIGTRAP, &m_old_SIGTRAP_action, sigaction_ptr() );
+ sigaction( SIGSEGV, &m_old_SIGSEGV_action, sigaction_ptr() );
+ sigaction( SIGBUS , &m_old_SIGBUS_action , sigaction_ptr() );
+ sigaction( SIGABRT, &m_old_SIGABRT_action, sigaction_ptr() );
+ }
s_active_handler = m_prev_handler;
}
//____________________________________________________________________________//
+} // namespace detail
+
// ************************************************************************** //
-// ************** execution_monitor_signal_handler ************** //
+// ************** execution_monitor::catch_signals ************** //
// ************************************************************************** //
-extern "C" {
-
-static void execution_monitor_jumping_signal_handler( int sig, siginfo_t* info, void* context )
+int
+execution_monitor::catch_signals( unit_test::callback0<int> const& F, bool catch_system_errors, int timeout )
{
- signal_handler::sys_sig()( info, context );
+ using namespace detail;
- siglongjmp( signal_handler::jump_buffer(), sig );
-}
+ signal_handler local_signal_handler( catch_system_errors, timeout );
-//____________________________________________________________________________//
+ volatile int sigtype = sigsetjmp( signal_handler::jump_buffer(), 1 );
-static void execution_monitor_attaching_signal_handler( int sig, siginfo_t* info, void* context )
-{
- execution_monitor_jumping_signal_handler( sig, info, context );
-}
+ typedef execution_exception::error_code ec_type;
+ int result = 0;
+ ec_type ec = execution_exception::no_error;
+ const_string em;
-//____________________________________________________________________________//
+ if( sigtype == 0 ) {
+ result = m_custom_translators ? (*m_custom_translators)( F ) : F();
+ }
+ else {
+ switch(sigtype) {
+ case SIGALRM:
+ ec = execution_exception::timeout_error;
+ em = BOOST_TEST_L( "signal: SIGALRM (timeout while executing function)" );
+ break;
+ case SIGTRAP:
+ ec = execution_exception::system_error;
+ em = BOOST_TEST_L( "signal: SIGTRAP (perhaps integer divide by zero)" );
+ break;
+ case SIGFPE:
+ ec = execution_exception::system_error;
+ em = BOOST_TEST_L( "signal: SIGFPE (arithmetic exception)" );
+ break;
+ case SIGABRT:
+ ec = execution_exception::system_error;
+ em = BOOST_TEST_L( "signal: SIGABRT (application abort requested)" );
+ break;
+ case SIGSEGV:
+ case SIGBUS:
+ ec = execution_exception::system_fatal_error;
+ em = BOOST_TEST_L( "memory access violation" );
+ break;
+ default:
+ ec = execution_exception::system_error;
+ em = BOOST_TEST_L( "unrecognized signal" );
+ }
+ }
-}
+ if( ec != execution_exception::no_error )
+ throw unix_signal_exception( ec, em );
-} // namespace detail
+ return result;
+} // unix catch_signals
-// ************************************************************************** //
-// ************** execution_monitor::catch_signals ************** //
-// ************************************************************************** //
+//____________________________________________________________________________//
+
+#elif (defined(__BORLANDC__) && defined(_Windows) && !defined(BOOST_DISABLE_WIN32))
+// this works for Borland but not other Win32 compilers (which trap too many cases)
int
-execution_monitor::catch_signals( unit_test::callback0<int> const& F )
+execution_monitor::catch_signals( unit_test::callback0<int> const& F, bool catch_system_errors, int )
{
- using namespace detail;
+ int result;
-#if defined(__CYGWIN__)
- p_catch_system_errors.value = false;
-#endif
+ if( catch_system_errors ) {
+ __try { result = m_custom_translators ? (*m_custom_translators)( F ) : F(); }
-#ifdef BOOST_TEST_USE_ALT_STACK
- if( !!p_use_alt_stack && !m_alt_stack )
- m_alt_stack.reset( new char[BOOST_TEST_ALT_STACK_SIZE] );
-#else
- p_use_alt_stack.value = false;
-#endif
-
- signal_handler local_signal_handler( p_catch_system_errors, p_timeout, p_auto_start_dbg,
- !p_use_alt_stack ? 0 : m_alt_stack.get() );
-
- if( !sigsetjmp( signal_handler::jump_buffer(), 1 ) )
- return detail::do_invoke( m_custom_translators , F );
+ __except (1) {
+ throw detail::ms_se_exception( GetExceptionCode() );
+ }
+ }
else
- throw local_signal_handler.sys_sig();
+ result = m_custom_translators ? (*m_custom_translators)( F ) : F();
+
+ return result;
}
-//____________________________________________________________________________//
+#else // default signal handler
-#elif defined(BOOST_SEH_BASED_SIGNAL_HANDLING)
+int
+execution_monitor::catch_signals( unit_test::callback0<int> const& F, bool, int )
+{
+ return m_custom_translators ? (*m_custom_translators)( F ) : F();
+}
+
+#endif // choose signal handler
// ************************************************************************** //
// ************** Microsoft structured exception handling ************** //
// ************************************************************************** //
-#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
-namespace { void _set_se_translator( void* ) {} }
-#endif
+#if defined(BOOST_MS_STRUCTURED_EXCEPTION_HANDLING)
namespace detail {
-// ************************************************************************** //
-// ************** boost::detail::system_signal_exception ************** //
-// ************************************************************************** //
-
-class system_signal_exception {
-public:
- // Constructor
- explicit system_signal_exception( execution_monitor* em )
- : m_em( em )
- , m_se_id( 0 )
- , m_fault_address( 0 )
- , m_dir( false )
- {}
-
- // access methods
- static void seh_catch_preventer( unsigned int /* id */, _EXCEPTION_POINTERS* /* exps */ )
- {
- throw;
- }
-
- void report() const;
- int operator()( unsigned int id, _EXCEPTION_POINTERS* exps );
-
-private:
- // Data members
- execution_monitor* m_em;
-
- unsigned int m_se_id;
- void* m_fault_address;
- bool m_dir;
-};
+void BOOST_TEST_CALL_DECL
+ms_se_trans_func( unsigned int id, _EXCEPTION_POINTERS* /* exps */ )
+{
+ throw ms_se_exception( id );
+}
//____________________________________________________________________________//
-int
-system_signal_exception::operator()( unsigned int id, _EXCEPTION_POINTERS* exps )
+void BOOST_TEST_CALL_DECL
+ms_se_forward_func( unsigned int /* id */, _EXCEPTION_POINTERS* /* exps */ )
{
- const unsigned int MSFT_CPP_EXCEPT = 0xE06d7363; // EMSC
-
- if( !m_em->p_catch_system_errors || (id == MSFT_CPP_EXCEPT) )
- return EXCEPTION_CONTINUE_SEARCH;
-
- m_se_id = id;
- if( m_se_id == EXCEPTION_ACCESS_VIOLATION && exps->ExceptionRecord->NumberParameters == 2 ) {
- m_fault_address = (void*)exps->ExceptionRecord->ExceptionInformation[1];
- m_dir = exps->ExceptionRecord->ExceptionInformation[0] == 0;
- }
-
- return EXCEPTION_EXECUTE_HANDLER;
+ throw;
}
//____________________________________________________________________________//
void
-system_signal_exception::report() const
+report_ms_se_error( unsigned int id )
{
- switch( m_se_id ) {
- // cases classified as system_fatal_error
- case EXCEPTION_ACCESS_VIOLATION: {
- if( !m_fault_address )
- detail::report_error( execution_exception::system_fatal_error, "memory access violation" );
- else
- detail::report_error(
- execution_exception::system_fatal_error,
- "memory access violation occurred at address 0x%08lx, while attempting to %s",
- m_fault_address,
- m_dir ? " read inaccessible data"
- : " write to an inaccessible (or protected) address"
- );
+ switch( id ) {
+ // cases classified as fatal_system_error
+ case EXCEPTION_ACCESS_VIOLATION:
+ detail::report_error( execution_exception::system_fatal_error, "memory access violation" );
break;
- }
case EXCEPTION_ILLEGAL_INSTRUCTION:
detail::report_error( execution_exception::system_fatal_error, "illegal instruction" );
break;
case EXCEPTION_PRIV_INSTRUCTION:
- detail::report_error( execution_exception::system_fatal_error, "tried to execute an instruction whose operation is not allowed in the current machine mode" );
+ detail::report_error( execution_exception::system_fatal_error, "privileged instruction" );
break;
case EXCEPTION_IN_PAGE_ERROR:
- detail::report_error( execution_exception::system_fatal_error, "access to a memory page that is not present" );
+ detail::report_error( execution_exception::system_fatal_error, "memory page error" );
break;
case EXCEPTION_STACK_OVERFLOW:
detail::report_error( execution_exception::system_fatal_error, "stack overflow" );
break;
- case EXCEPTION_NONCONTINUABLE_EXCEPTION:
- detail::report_error( execution_exception::system_fatal_error, "tried to continue execution after a non continuable exception occurred" );
- break;
-
- // cases classified as (non-fatal) system_trap
+ // cases classified as (non-fatal) system_trap
case EXCEPTION_DATATYPE_MISALIGNMENT:
detail::report_error( execution_exception::system_error, "data misalignment" );
break;
@@ -805,108 +570,45 @@
break;
case EXCEPTION_FLT_STACK_CHECK:
- detail::report_error( execution_exception::system_error,
- "stack overflowed or underflowed as the result of a floating-point operation" );
+ detail::report_error( execution_exception::system_error, "floating point stack check" );
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
- detail::report_error( execution_exception::system_error,
- "operand of floating point operation is denormal" );
- break;
-
-# if 0 // !! ??
case EXCEPTION_FLT_INEXACT_RESULT:
- detail::report_error( execution_exception::system_error,
- "result of a floating-point operation cannot be represented exactly" );
- break;
-#endif
-
+ case EXCEPTION_FLT_INVALID_OPERATION:
case EXCEPTION_FLT_OVERFLOW:
- detail::report_error( execution_exception::system_error,
- "exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type" );
- break;
-
case EXCEPTION_FLT_UNDERFLOW:
- detail::report_error( execution_exception::system_error,
- "exponent of a floating-point operation is less than the magnitude allowed by the corresponding type" );
- break;
-
- case EXCEPTION_FLT_INVALID_OPERATION:
detail::report_error( execution_exception::system_error, "floating point error" );
break;
- case EXCEPTION_BREAKPOINT:
- detail::report_error( execution_exception::system_error, "breakpoint encountered" );
- break;
-
default:
- detail::report_error( execution_exception::system_error, "unrecognized exception. Id: 0x%08lx", m_se_id );
+ detail::report_error( execution_exception::system_error, "unrecognized exception or signal" );
break;
- }
-}
+ } // switch
+} // report_ms_se_error
//____________________________________________________________________________//
-#if defined(BOOST_TEST_USE_DEBUG_MS_CRT)
+} // namespace detail
+
+#endif // Microsoft structured exception handling
// ************************************************************************** //
-// ************** assert_reporting_function ************** //
+// ************** report_error ************** //
// ************************************************************************** //
-int BOOST_TEST_CALL_DECL
-assert_reporting_function( int reportType, char* userMessage, int* retVal )
-{
- switch( reportType ) {
- case _CRT_ASSERT:
- detail::report_error( execution_exception::user_error, userMessage );
-
- return 1; // return value and retVal are not important since we never reach this line
- case _CRT_ERROR:
- detail::report_error( execution_exception::system_error, userMessage );
-
- return 1; // return value and retVal are not important since we never reach this line
- default:
- return 0; // use usual reporting method
- }
-} // assert_reporting_function
-
-#endif
-
-//____________________________________________________________________________//
-
-void BOOST_TEST_CALL_DECL
-invalid_param_handler( wchar_t const* /* expr */,
- wchar_t const* /* func */,
- wchar_t const* /* file */,
- unsigned int /* line */,
- uintptr_t /* reserved */)
-{
- detail::report_error( execution_exception::user_error,
- "Invalid parameter detected by C runtime library" );
-}
-
-//____________________________________________________________________________//
+namespace detail {
-void BOOST_TEST_CALL_DECL
-switch_fp_exceptions( bool on_off )
+static void report_error( execution_exception::error_code ec, const_string msg1, const_string msg2 )
{
- if( !on_off )
- _clearfp();
-
- int cw = ::_controlfp( 0, 0 );
+ static char buf[REPORT_ERROR_BUFFER_SIZE];
- int exceptions_mask = _EM_INVALID|_EM_DENORMAL|_EM_ZERODIVIDE|_EM_OVERFLOW|_EM_UNDERFLOW;
+ buf[0] = '\0';
- if( on_off )
- cw &= ~exceptions_mask; // Set the exception masks on, turn exceptions off
- else
- cw |= exceptions_mask; // Set the exception masks off, turn exceptions on
+ std::strncat( buf, msg1.begin(), sizeof(buf)-1 );
+ std::strncat( buf, msg2.begin(), sizeof(buf) - msg1.size() - 1 );
- if( on_off )
- _clearfp();
-
- // Set the control word
- ::_controlfp( cw, _MCW_EM );
+ throw execution_exception( ec, buf );
}
//____________________________________________________________________________//
@@ -914,158 +616,40 @@
} // namespace detail
// ************************************************************************** //
-// ************** execution_monitor::catch_signals ************** //
+// ************** detect_memory_leaks ************** //
// ************************************************************************** //
-int
-execution_monitor::catch_signals( unit_test::callback0<int> const& F )
+void
+detect_memory_leaks( bool on_off )
{
- _invalid_parameter_handler old_iph;
-
- if( !p_catch_system_errors )
- _set_se_translator( &detail::system_signal_exception::seh_catch_preventer );
- else {
- detail::switch_fp_exceptions( true );
-
-#ifdef BOOST_TEST_USE_DEBUG_MS_CRT
- _CrtSetReportHook( &detail::assert_reporting_function );
-#endif
-
- old_iph = _set_invalid_parameter_handler(
- reinterpret_cast<_invalid_parameter_handler>( &detail::invalid_param_handler ) );
- }
-
- detail::system_signal_exception SSE( this );
+ unit_test::ut_detail::ignore_unused_variable_warning( on_off );
- __try {
- __try {
- return detail::do_invoke( m_custom_translators , F );
- }
- __except( SSE( GetExceptionCode(), GetExceptionInformation() ) ) {
- throw SSE;
- }
- }
- __finally {
- if( !!p_catch_system_errors ) {
- detail::switch_fp_exceptions( false );
+#ifdef BOOST_MS_CRT_DEBUG_HOOKS
+ int flags = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
- _set_invalid_parameter_handler( old_iph );
-
- }
+ if( !on_off )
+ flags &= ~_CRTDBG_LEAK_CHECK_DF;
+ else {
+ flags |= _CRTDBG_LEAK_CHECK_DF;
+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
}
- return 0;
+ _CrtSetDbgFlag ( flags );
+#endif // BOOST_MS_CRT_DEBUG_HOOKS
}
//____________________________________________________________________________//
-#else // default signal handler
-
-namespace detail {
-
-class system_signal_exception {
-public:
- void report() const {}
-};
-
-} // namespace detail
-
-int
-execution_monitor::catch_signals( unit_test::callback0<int> const& F )
-{
- return detail::do_invoke( m_custom_translators , F );
-}
-
-//____________________________________________________________________________//
-
-#endif // choose signal handler
-
-// ************************************************************************** //
-// ************** execution_monitor::execute ************** //
-// ************************************************************************** //
-
-int
-execution_monitor::execute( unit_test::callback0<int> const& F )
+void
+break_memory_alloc( long mem_alloc_order_num )
{
- try {
- return catch_signals( F );
- }
-
- // Catch-clause reference arguments are a bit different from function
- // arguments (ISO 15.3 paragraphs 18 & 19). Apparently const isn't
- // required. Programmers ask for const anyhow, so we supply it. That's
- // easier than answering questions about non-const usage.
-
- catch( char const* ex )
- { detail::report_error( execution_exception::cpp_exception_error, "C string: %s", ex ); }
- catch( std::string const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::string: %s", ex.c_str() ); }
-
- // std:: exceptions
-
- catch( std::bad_alloc const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::bad_alloc: %s", ex.what() ); }
+ unit_test::ut_detail::ignore_unused_variable_warning( mem_alloc_order_num );
-#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
- catch( std::bad_cast const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::bad_cast" ); }
- catch( std::bad_typeid const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::bad_typeid" ); }
-#else
- catch( std::bad_cast const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::bad_cast: %s", ex.what() ); }
- catch( std::bad_typeid const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::bad_typeid: %s", ex.what() ); }
-#endif
-
- catch( std::bad_exception const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::bad_exception: %s", ex.what() ); }
- catch( std::domain_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::domain_error: %s", ex.what() ); }
- catch( std::invalid_argument const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::invalid_argument: %s", ex.what() ); }
- catch( std::length_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::length_error: %s", ex.what() ); }
- catch( std::out_of_range const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::out_of_range: %s", ex.what() ); }
- catch( std::range_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::range_error: %s", ex.what() ); }
- catch( std::overflow_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::overflow_error: %s", ex.what() ); }
- catch( std::underflow_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::underflow_error: %s", ex.what() ); }
- catch( std::logic_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::logic_error: %s", ex.what() ); }
- catch( std::runtime_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::runtime_error: %s", ex.what() ); }
- catch( std::exception const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "std::exception: %s", ex.what() ); }
- catch( system_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error, "system_error: %s", std::strerror( ex.p_errno ) ); }
- catch( detail::system_signal_exception const& ex )
- { ex.report(); }
- catch( execution_aborted const& )
- { return 0; }
- catch( execution_exception const& )
- { throw; }
-
- catch( ... )
- { detail::report_error( execution_exception::cpp_exception_error, "unknown type" ); }
-
- return 0; // never reached; supplied to quiet compiler warnings
-} // execute
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** system_error ************** //
-// ************************************************************************** //
-
-system_error::system_error()
-: p_errno( errno )
-{}
-
-//____________________________________________________________________________//
+#ifdef BOOST_MS_CRT_DEBUG_HOOKS
+ _CrtSetBreakAlloc( mem_alloc_order_num );
+#endif // BOOST_MS_CRT_DEBUG_HOOKS
+}
} // namespace boost
@@ -1077,6 +661,51 @@
// Revision History :
//
// $Log$
+// Revision 1.13 2006/02/22 16:14:45 rogeeff
+// reagance to eliminate warning
+//
+// Revision 1.12 2006/01/30 07:29:49 rogeeff
+// split memory leaks detection API in two to get more functions with better defined roles
+//
+// Revision 1.11 2006/01/15 09:47:43 rogeeff
+// make common message
+//
+// Revision 1.10 2005/12/14 05:52:49 rogeeff
+// *** empty log message ***
+//
+// Revision 1.9 2005/04/30 17:07:22 rogeeff
+// ignore_warning included
+//
+// Revision 1.8 2005/04/30 16:46:50 rogeeff
+// warning suppressed
+//
+// Revision 1.7 2005/04/13 05:32:03 rogeeff
+// typo fix
+//
+// Revision 1.6 2005/04/05 06:11:37 rogeeff
+// memory leak allocation point detection\nextra help with _WIN32_WINNT
+//
+// Revision 1.5 2005/02/20 08:27:07 rogeeff
+// This a major update for Boost.Test framework. See release docs for complete list of fixes/updates
+//
+// Revision 1.4 2005/02/01 06:40:07 rogeeff
+// copyright update
+// old log entries removed
+// minor stilistic changes
+// depricated tools removed
+//
+// Revision 1.3 2005/01/31 07:50:06 rogeeff
+// cdecl portability fix
+//
+// Revision 1.2 2005/01/31 05:58:03 rogeeff
+// detect_memory_leak feature added
+//
+// Revision 1.1 2005/01/22 19:22:12 rogeeff
+// implementation moved into headers section to eliminate dependency of included/minimal component on src directory
+//
+// Revision 1.36 2005/01/21 07:21:38 rogeeff
+// detect presence of debugger under VC and automatically prevent catching system errors
+//
// ***************************************************************************
#endif // BOOST_TEST_EXECUTION_MONITOR_IPP_012205GER
Modified: trunk/boost/test/impl/framework.ipp
==============================================================================
--- trunk/boost/test/impl/framework.ipp (original)
+++ trunk/boost/test/impl/framework.ipp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -49,6 +49,17 @@
//____________________________________________________________________________//
+#ifndef BOOST_TEST_DYN_LINK
+
+// prototype for user's unit test init function
+#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
+extern bool init_unit_test();
+#else
+extern boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] );
+#endif
+
+#endif
+
namespace boost {
namespace unit_test {
@@ -77,29 +88,6 @@
counter_t m_tc_amount;
};
-//____________________________________________________________________________//
-
-struct test_init_caller {
- explicit test_init_caller( init_unit_test_func init_func )
- : m_manual_test_units( 0 )
- , m_init_func( init_func )
- {}
- int operator()()
- {
-#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
- if( !(*m_init_func)() )
- throw std::runtime_error( "test module initialization failed" );
-#else
- m_manual_test_units = (*m_init_func)( framework::master_test_suite().argc, framework::master_test_suite().argv );
-#endif
- return 0;
- }
-
- // Data members
- test_suite* m_manual_test_units;
- init_unit_test_func m_init_func;
-};
-
}
// ************************************************************************** //
@@ -219,7 +207,7 @@
namespace framework {
void
-init( init_unit_test_func init_func, int argc, char* argv[] )
+init( int argc, char* argv[] )
{
runtime_config::init( &argc, argv );
@@ -238,27 +226,27 @@
register_observer( progress_monitor );
if( runtime_config::detect_memory_leaks() > 0 ) {
-// detect_memory_leaks( true );
-// break_memory_alloc( runtime_config::detect_memory_leaks() );
+ detect_memory_leaks( true );
+ break_memory_alloc( runtime_config::detect_memory_leaks() );
}
// init master unit test suite
master_test_suite().argc = argc;
master_test_suite().argv = argv;
- try {
- boost::execution_monitor em;
+#ifndef BOOST_TEST_DYN_LINK
- ut_detail::test_init_caller tic( init_func );
+#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
+ if( !init_unit_test() )
+ throw setup_error( BOOST_TEST_L("test tree initialization error" ) );
+#else
+ test_suite* s = init_unit_test_suite( argc, argv );
+ if( s )
+ master_test_suite().add( s );
+#endif
- em.execute( tic );
+#endif
- if( tic.m_manual_test_units )
- master_test_suite().add( tic.m_manual_test_units );
- }
- catch( execution_exception const& ex ) {
- throw setup_error( ex.what() );
- }
}
//____________________________________________________________________________//
@@ -466,4 +454,41 @@
#include <boost/test/detail/enable_warnings.hpp>
+// ***************************************************************************
+// Revision History :
+//
+// $Log$
+// Revision 1.10 2006/03/19 07:27:52 rogeeff
+// streamline test setup error message
+//
+// Revision 1.9 2006/01/30 07:29:49 rogeeff
+// split memory leaks detection API in two to get more functions with better defined roles
+//
+// Revision 1.8 2005/12/17 02:34:11 rogeeff
+// *** empty log message ***
+//
+// Revision 1.7 2005/12/14 05:35:57 rogeeff
+// DLL support implemented
+// Alternative init API introduced
+//
+// Revision 1.6 2005/05/08 08:55:09 rogeeff
+// typos and missing descriptions fixed
+//
+// Revision 1.5 2005/04/05 07:23:20 rogeeff
+// restore default
+//
+// Revision 1.4 2005/04/05 06:11:37 rogeeff
+// memory leak allocation point detection\nextra help with _WIN32_WINNT
+//
+// Revision 1.3 2005/03/23 21:02:19 rogeeff
+// Sunpro CC 5.3 fixes
+//
+// Revision 1.2 2005/02/21 10:12:18 rogeeff
+// Support for random order of test cases implemented
+//
+// Revision 1.1 2005/02/20 08:27:07 rogeeff
+// This a major update for Boost.Test framework. See release docs for complete list of fixes/updates
+//
+// ***************************************************************************
+
#endif // BOOST_TEST_FRAMEWORK_IPP_021005GER
Modified: trunk/boost/test/impl/results_reporter.ipp
==============================================================================
--- trunk/boost/test/impl/results_reporter.ipp (original)
+++ trunk/boost/test/impl/results_reporter.ipp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -23,10 +23,10 @@
#include <boost/test/output/plain_report_formatter.hpp>
#include <boost/test/output/xml_report_formatter.hpp>
+#include <boost/test/detail/wrap_io_saver.hpp>
+
// Boost
#include <boost/scoped_ptr.hpp>
-#include <boost/io/ios_state.hpp>
-typedef ::boost::io::ios_base_all_saver io_saver_type;
// STL
#include <iostream>
Modified: trunk/boost/test/impl/unit_test_log.ipp
==============================================================================
--- trunk/boost/test/impl/unit_test_log.ipp (original)
+++ trunk/boost/test/impl/unit_test_log.ipp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -22,6 +22,7 @@
#include <boost/test/execution_monitor.hpp>
#include <boost/test/detail/unit_test_parameters.hpp>
+#include <boost/test/detail/wrap_io_saver.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
@@ -30,8 +31,6 @@
// Boost
#include <boost/scoped_ptr.hpp>
-#include <boost/io/ios_state.hpp>
-typedef ::boost::io::ios_base_all_saver io_saver_type;
// STL
#include <iostream>
Modified: trunk/boost/test/impl/unit_test_main.ipp
==============================================================================
--- trunk/boost/test/impl/unit_test_main.ipp (original)
+++ trunk/boost/test/impl/unit_test_main.ipp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -43,11 +43,20 @@
// ************************************************************************** //
int BOOST_TEST_DECL
-unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
+
+#if defined(BOOST_TEST_DYN_LINK)
+unit_test_main( bool (*init_unit_test_func)(), int argc, char* argv[] )
+#else
+unit_test_main( int argc, char* argv[] )
+#endif
{
try {
- framework::init( init_func, argc, argv );
+ framework::init( argc, argv );
+#ifdef BOOST_TEST_DYN_LINK
+ if( !(*init_unit_test_func)() )
+ throw framework::setup_error( BOOST_TEST_L( "test tree initialization error" ) );
+#endif
// !! ?? if( !runtime_config.test_to_run().is_empty() ) {
//
// }
@@ -90,18 +99,7 @@
int BOOST_TEST_CALL_DECL
main( int argc, char* argv[] )
{
- // prototype for user's unit test init function
-#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
- extern bool init_unit_test();
-
- boost::unit_test::init_unit_test_func init_func = &init_unit_test;
-#else
- extern ::boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] );
-
- boost::unit_test::init_unit_test_func init_func = &init_unit_test_suite;
-#endif
-
- return ::boost::unit_test::unit_test_main( init_func, argc, argv );
+ return ::boost::unit_test::unit_test_main( argc, argv );
}
#endif // !BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN
Modified: trunk/boost/test/impl/unit_test_monitor.ipp
==============================================================================
--- trunk/boost/test/impl/unit_test_monitor.ipp (original)
+++ trunk/boost/test/impl/unit_test_monitor.ipp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -60,12 +60,9 @@
unit_test_monitor_t::execute_and_translate( test_case const& tc )
{
try {
- p_catch_system_errors.value = runtime_config::catch_sys_errors();
- p_timeout.value = tc.p_timeout.get();
- p_auto_start_dbg.value = runtime_config::auto_start_dbg();
- p_use_alt_stack.value = runtime_config::use_alt_stack();
-
- execute( callback0<int>( zero_return_wrapper( tc.test_func() ) ) );
+ execute( callback0<int>( zero_return_wrapper( tc.test_func() ) ),
+ runtime_config::catch_sys_errors(),
+ tc.p_timeout );
}
catch( execution_exception const& ex ) {
framework::exception_caught( ex );
Modified: trunk/boost/test/impl/unit_test_suite.ipp
==============================================================================
--- trunk/boost/test/impl/unit_test_suite.ipp (original)
+++ trunk/boost/test/impl/unit_test_suite.ipp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -54,7 +54,6 @@
, p_type_name( t == tut_case ? "case" : "suite" )
, p_id( INV_TEST_UNIT_ID )
, p_name( std::string( name.begin(), name.size() ) )
-, p_enabled( true )
{
}
@@ -156,7 +155,7 @@
test_suite::get( const_string tu_name ) const
{
BOOST_TEST_FOREACH( test_unit_id, id, m_members ) {
- if( tu_name == framework::get( id, test_id_2_unit_type( id ) ).p_name.get() )
+ if( framework::get( id, test_id_2_unit_type( id ) ).p_name == tu_name )
return id;
}
@@ -172,7 +171,6 @@
void
traverse_test_tree( test_case const& tc, test_tree_visitor& V )
{
- if( tc.p_enabled )
V.visit( tc );
}
@@ -181,7 +179,7 @@
void
traverse_test_tree( test_suite const& suite, test_tree_visitor& V )
{
- if( !suite.p_enabled || !V.test_suite_start( suite ) )
+ if( !V.test_suite_start( suite ) )
return;
try {
Modified: trunk/boost/test/interaction_based.hpp
==============================================================================
--- trunk/boost/test/interaction_based.hpp (original)
+++ trunk/boost/test/interaction_based.hpp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -115,8 +115,8 @@
std::size_t /*line_num*/,
void* /*p*/, std::size_t /*s*/ ) {}
virtual void freed( void* /*p*/ ) {}
- virtual void data_flow( const_string /*d*/ ) {}
- virtual std::string return_value( const_string /*default_value */ ) { return ""; }
+ virtual void data_flow( const_string d ) {}
+ virtual std::string return_value( const_string default_value ) { return ""; }
template<typename T>
void generic_data_flow( T const& t )
Modified: trunk/boost/test/unit_test.hpp
==============================================================================
--- trunk/boost/test/unit_test.hpp (original)
+++ trunk/boost/test/unit_test.hpp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -43,7 +43,15 @@
namespace boost { namespace unit_test {
-int BOOST_TEST_DECL unit_test_main( init_unit_test_func init_func, int argc, char* argv[] );
+#if defined(BOOST_TEST_DYN_LINK)
+
+int BOOST_TEST_DECL unit_test_main( bool (*init_unit_test_func)(), int argc, char* argv[] );
+
+#else
+
+int BOOST_TEST_DECL unit_test_main( int argc, char* argv[] );
+
+#endif
}}
Modified: trunk/boost/test/unit_test_suite_impl.hpp
==============================================================================
--- trunk/boost/test/unit_test_suite_impl.hpp (original)
+++ trunk/boost/test/unit_test_suite_impl.hpp 2007-10-16 15:07:12 EDT (Tue, 16 Oct 2007)
@@ -67,7 +67,6 @@
readwrite_property<std::string> p_name; // name for this test unit
readwrite_property<unsigned> p_timeout; // timeout for the test unit execution
readwrite_property<counter_t> p_expected_failures; // number of expected failures in this test unit
- mutable readwrite_property<bool> p_enabled; // enabled status for this unit
void increase_exp_fail( unsigned num );
@@ -199,7 +198,7 @@
struct test_case_counter : test_tree_visitor {
test_case_counter() : m_count( 0 ) {}
- virtual void visit( test_case const& ) { m_count++; }
+ void visit( test_case const& ) { m_count++; }
counter_t m_count;
};
@@ -277,9 +276,7 @@
template<typename T>
struct auto_tc_exp_fail {
- auto_tc_exp_fail() : m_value( 0 ) {}
-
- explicit auto_tc_exp_fail( unsigned v )
+ explicit auto_tc_exp_fail( unsigned v = 0 )
: m_value( v )
{
instance() = this;
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk