annotate DEPENDENCIES/generic/include/boost/test/execution_monitor.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // (C) Copyright Gennadiy Rozental 2001-2008.
Chris@16 2 // (C) Copyright Beman Dawes 2001.
Chris@16 3 // Distributed under the Boost Software License, Version 1.0.
Chris@16 4 // (See accompanying file LICENSE_1_0.txt or copy at
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 : defines abstract monitor interfaces and implements execution exception
Chris@16 14 // The original Boost Test Library included an implementation detail function
Chris@16 15 // named catch_exceptions() which caught otherwise uncaught C++ exceptions.
Chris@16 16 // It was derived from an existing test framework by Beman Dawes. The
Chris@16 17 // intent was to expand later to catch other detectable but platform dependent
Chris@16 18 // error events like Unix signals or Windows structured C exceptions.
Chris@16 19 //
Chris@16 20 // Requests from early adopters of the Boost Test Library included
Chris@16 21 // configurable levels of error message detail, elimination of templates,
Chris@16 22 // separation of error reporting, and making the catch_exceptions() facilities
Chris@16 23 // available as a public interface. Support for unit testing also stretched
Chris@16 24 // the function based design. Implementation within the header became less
Chris@16 25 // attractive due to the need to include many huge system dependent headers,
Chris@16 26 // although still preferable in certain cases.
Chris@16 27 //
Chris@16 28 // All those issues have been addressed by introducing the class-based
Chris@16 29 // design presented here.
Chris@16 30 // ***************************************************************************
Chris@16 31
Chris@16 32 #ifndef BOOST_TEST_EXECUTION_MONITOR_HPP_071894GER
Chris@16 33 #define BOOST_TEST_EXECUTION_MONITOR_HPP_071894GER
Chris@16 34
Chris@16 35 // Boost.Test
Chris@16 36 #include <boost/test/detail/global_typedef.hpp>
Chris@16 37 #include <boost/test/detail/fwd_decl.hpp>
Chris@16 38 #include <boost/test/utils/callback.hpp>
Chris@16 39 #include <boost/test/utils/class_properties.hpp>
Chris@16 40
Chris@16 41 // Boost
Chris@16 42 #include <boost/scoped_ptr.hpp>
Chris@16 43 #include <boost/scoped_array.hpp>
Chris@16 44 #include <boost/type.hpp>
Chris@16 45 #include <boost/cstdlib.hpp>
Chris@16 46
Chris@16 47 #include <boost/test/detail/suppress_warnings.hpp>
Chris@16 48
Chris@16 49 //____________________________________________________________________________//
Chris@16 50
Chris@16 51 namespace boost {
Chris@16 52
Chris@16 53 namespace detail {
Chris@16 54
Chris@16 55 // ************************************************************************** //
Chris@16 56 // ************** detail::translate_exception_base ************** //
Chris@16 57 // ************************************************************************** //
Chris@16 58
Chris@16 59 class BOOST_TEST_DECL translate_exception_base {
Chris@16 60 public:
Chris@16 61 // Constructor
Chris@16 62 explicit translate_exception_base( boost::scoped_ptr<translate_exception_base>& next )
Chris@16 63 {
Chris@16 64 next.swap( m_next );
Chris@16 65 }
Chris@16 66
Chris@16 67 // Destructor
Chris@16 68 virtual ~translate_exception_base() {}
Chris@16 69
Chris@16 70 virtual int operator()( unit_test::callback0<int> const& F ) = 0;
Chris@16 71
Chris@16 72 protected:
Chris@16 73 // Data members
Chris@16 74 boost::scoped_ptr<translate_exception_base> m_next;
Chris@16 75 };
Chris@16 76
Chris@16 77 } // namespace detail
Chris@16 78
Chris@16 79 // ************************************************************************** //
Chris@16 80 // ************** execution_exception ************** //
Chris@16 81 // ************************************************************************** //
Chris@16 82
Chris@16 83 // design rationale: fear of being out (or nearly out) of memory.
Chris@16 84
Chris@16 85 class BOOST_TEST_DECL execution_exception {
Chris@16 86 typedef boost::unit_test::const_string const_string;
Chris@16 87 public:
Chris@16 88 enum error_code {
Chris@16 89 // These values are sometimes used as program return codes.
Chris@16 90 // The particular values have been chosen to avoid conflicts with
Chris@16 91 // commonly used program return codes: values < 100 are often user
Chris@16 92 // assigned, values > 255 are sometimes used to report system errors.
Chris@16 93 // Gaps in values allow for orderly expansion.
Chris@16 94
Chris@16 95 no_error = 0, // for completeness only; never returned
Chris@16 96 user_error = 200, // user reported non-fatal error
Chris@16 97 cpp_exception_error = 205, // see note (1) below
Chris@16 98 system_error = 210, // see note (2) below
Chris@16 99 timeout_error = 215, // only detectable on certain platforms
Chris@16 100 user_fatal_error = 220, // user reported fatal error
Chris@16 101 system_fatal_error = 225 // see note (2) below
Chris@16 102
Chris@16 103 // Note 1: Only uncaught C++ exceptions are treated as errors.
Chris@16 104 // If the application catches a C++ exception, it will never reach
Chris@16 105 // the execution_monitor.
Chris@16 106
Chris@16 107 // Note 2: These errors include Unix signals and Windows structured
Chris@16 108 // exceptions. They are often initiated by hardware traps.
Chris@16 109 //
Chris@16 110 // The implementation decides what is a fatal_system_exception and what is
Chris@16 111 // just a system_exception. Fatal errors are so likely to have corrupted
Chris@16 112 // machine state (like a stack overflow or addressing exception) that it
Chris@16 113 // is unreasonable to continue execution.
Chris@16 114 };
Chris@16 115
Chris@16 116 struct BOOST_TEST_DECL location {
Chris@16 117 explicit location( char const* file_name = 0, size_t line_num = 0, char const* func = 0 );
Chris@16 118
Chris@16 119 const_string m_file_name;
Chris@16 120 size_t m_line_num;
Chris@16 121 const_string m_function;
Chris@16 122 };
Chris@16 123
Chris@16 124 // Constructor
Chris@16 125 execution_exception( error_code ec_, const_string what_msg_, location const& location_ ); // max length 256 inc '\0'
Chris@16 126
Chris@16 127 // Access methods
Chris@16 128 error_code code() const { return m_error_code; }
Chris@16 129 const_string what() const { return m_what; }
Chris@16 130 location const& where() const { return m_location; }
Chris@16 131
Chris@16 132 private:
Chris@16 133 // Data members
Chris@16 134 error_code m_error_code;
Chris@16 135 const_string m_what;
Chris@16 136 location m_location;
Chris@16 137 }; // execution_exception
Chris@16 138
Chris@16 139 // ************************************************************************** //
Chris@16 140 // ************** execution_monitor ************** //
Chris@16 141 // ************************************************************************** //
Chris@16 142
Chris@16 143 class BOOST_TEST_DECL execution_monitor {
Chris@16 144 public:
Chris@16 145 // Constructor
Chris@16 146 execution_monitor()
Chris@16 147 : p_catch_system_errors( true )
Chris@16 148 , p_auto_start_dbg( false )
Chris@16 149 , p_timeout( 0 )
Chris@16 150 , p_use_alt_stack( true )
Chris@16 151 , p_detect_fp_exceptions( false )
Chris@16 152 {}
Chris@16 153
Chris@16 154 // Public properties
Chris@16 155
Chris@16 156 // The p_catch_system_errors parameter specifies whether the monitor should
Chris@16 157 // try to catch system errors/exceptions that would cause program to crash
Chris@16 158 // in regular case
Chris@16 159 unit_test::readwrite_property<bool> p_catch_system_errors;
Chris@16 160 // The p_auto_start_dbg parameter specifies whether the monitor should
Chris@16 161 // try to attach debugger in case of caught system error
Chris@16 162 unit_test::readwrite_property<bool> p_auto_start_dbg;
Chris@16 163 // The p_timeout parameter specifies the seconds that elapse before
Chris@16 164 // a timer_error occurs. May be ignored on some platforms.
Chris@16 165 unit_test::readwrite_property<int> p_timeout;
Chris@16 166 // The p_use_alt_stack parameter specifies whether the monitor should
Chris@16 167 // use alternative stack for the signal catching
Chris@16 168 unit_test::readwrite_property<bool> p_use_alt_stack;
Chris@16 169 // The p_detect_fp_exceptions parameter specifies whether the monitor should
Chris@16 170 // try to detect hardware floating point exceptions
Chris@16 171 unit_test::readwrite_property<bool> p_detect_fp_exceptions;
Chris@16 172
Chris@16 173 int execute( unit_test::callback0<int> const& F );
Chris@16 174 // Returns: Value returned by function call F().
Chris@16 175 //
Chris@16 176 // Effects: Calls executes supplied function F inside a try/catch block which also may
Chris@16 177 // include other unspecified platform dependent error detection code.
Chris@16 178 //
Chris@16 179 // Throws: execution_exception on an uncaught C++ exception,
Chris@16 180 // a hardware or software signal, trap, or other exception.
Chris@16 181 //
Chris@16 182 // Note: execute() doesn't consider it an error for F to return a non-zero value.
Chris@16 183
Chris@16 184 // register custom (user supplied) exception translator
Chris@16 185 template<typename Exception, typename ExceptionTranslator>
Chris@16 186 void register_exception_translator( ExceptionTranslator const& tr, boost::type<Exception>* = 0 );
Chris@16 187
Chris@16 188 private:
Chris@16 189 // implementation helpers
Chris@16 190 int catch_signals( unit_test::callback0<int> const& F );
Chris@16 191
Chris@16 192 // Data members
Chris@16 193 boost::scoped_ptr<detail::translate_exception_base> m_custom_translators;
Chris@16 194 boost::scoped_array<char> m_alt_stack;
Chris@16 195 }; // execution_monitor
Chris@16 196
Chris@16 197 namespace detail {
Chris@16 198
Chris@16 199 // ************************************************************************** //
Chris@16 200 // ************** detail::translate_exception ************** //
Chris@16 201 // ************************************************************************** //
Chris@16 202
Chris@16 203 template<typename Exception, typename ExceptionTranslator>
Chris@16 204 class translate_exception : public translate_exception_base
Chris@16 205 {
Chris@16 206 typedef boost::scoped_ptr<translate_exception_base> base_ptr;
Chris@16 207 public:
Chris@16 208 explicit translate_exception( ExceptionTranslator const& tr, base_ptr& next )
Chris@16 209 : translate_exception_base( next ), m_translator( tr ) {}
Chris@16 210
Chris@16 211 int operator()( unit_test::callback0<int> const& F )
Chris@16 212 {
Chris@16 213 try {
Chris@16 214 return m_next ? (*m_next)( F ) : F();
Chris@16 215 } catch( Exception const& e ) {
Chris@16 216 m_translator( e );
Chris@16 217 return boost::exit_exception_failure;
Chris@16 218 }
Chris@16 219 }
Chris@16 220
Chris@16 221 private:
Chris@16 222 // Data members
Chris@16 223 ExceptionTranslator m_translator;
Chris@16 224 };
Chris@16 225
Chris@16 226 } // namespace detail
Chris@16 227
Chris@16 228 template<typename Exception, typename ExceptionTranslator>
Chris@16 229 void
Chris@16 230 execution_monitor::register_exception_translator( ExceptionTranslator const& tr, boost::type<Exception>* )
Chris@16 231 {
Chris@16 232 m_custom_translators.reset(
Chris@16 233 new detail::translate_exception<Exception,ExceptionTranslator>( tr,m_custom_translators ) );
Chris@16 234 }
Chris@16 235
Chris@16 236 // ************************************************************************** //
Chris@16 237 // ************** execution_aborted ************** //
Chris@16 238 // ************************************************************************** //
Chris@16 239
Chris@16 240 struct execution_aborted {};
Chris@16 241
Chris@16 242 // ************************************************************************** //
Chris@16 243 // ************** system_error ************** //
Chris@16 244 // ************************************************************************** //
Chris@16 245
Chris@16 246 class system_error {
Chris@16 247 public:
Chris@16 248 // Constructor
Chris@16 249 explicit system_error( char const* exp );
Chris@16 250
Chris@16 251 unit_test::readonly_property<long> p_errno;
Chris@16 252 unit_test::readonly_property<char const*> p_failed_exp;
Chris@16 253 };
Chris@16 254
Chris@16 255 #define BOOST_TEST_SYS_ASSERT( exp ) if( (exp) ) ; else throw ::boost::system_error( BOOST_STRINGIZE( exp ) )
Chris@16 256
Chris@16 257 } // namespace boost
Chris@16 258
Chris@16 259 //____________________________________________________________________________//
Chris@16 260
Chris@16 261 #include <boost/test/detail/enable_warnings.hpp>
Chris@16 262
Chris@16 263 #endif