|
|
@ -9,6 +9,9 @@ |
|
|
|
@license LGPL, see file <a href="license.html">COPYING</a> |
|
|
|
@license LGPL, see file <a href="license.html">COPYING</a> |
|
|
|
|
|
|
|
|
|
|
|
$Log$ |
|
|
|
$Log$ |
|
|
|
|
|
|
|
Revision 1.5 2005/01/28 07:42:23 marc |
|
|
|
|
|
|
|
added terminate handler (uncaught handler) |
|
|
|
|
|
|
|
|
|
|
|
Revision 1.4 2004/10/13 10:41:28 marc |
|
|
|
Revision 1.4 2004/10/13 10:41:28 marc |
|
|
|
no newline at the end of stack trace |
|
|
|
no newline at the end of stack trace |
|
|
|
|
|
|
|
|
|
|
@ -36,21 +39,26 @@ namespace mrw { |
|
|
|
/** @addtogroup StackTrace */ |
|
|
|
/** @addtogroup StackTrace */ |
|
|
|
//@{
|
|
|
|
//@{
|
|
|
|
|
|
|
|
|
|
|
|
/** @defgroup AutoTrace Automated Unexpected Handler with Stack Trace
|
|
|
|
/** @defgroup AutoTrace Automated Unexpected and Terminate Handler
|
|
|
|
|
|
|
|
with Stack Trace |
|
|
|
|
|
|
|
|
|
|
|
@brief Don't care about the unexpected handler, let the library |
|
|
|
@brief Don't care about the unexpected handler, don't care about |
|
|
|
do all the repetitive work for you. |
|
|
|
a try-catch in the main, let the library do all the repetitive |
|
|
|
|
|
|
|
work for you. |
|
|
|
|
|
|
|
|
|
|
|
For all your programs it is recommended to implement an identical |
|
|
|
For all your programs it is recommended to implement an |
|
|
|
unexpected handler, that rethrows, catches the @c |
|
|
|
identical unexpected handler, that rethrows, catches the @c |
|
|
|
mrw::exception, @c std::exception and all unknown exceptions, |
|
|
|
mrw::exception, @c std::exception and all unknown exceptions, |
|
|
|
traces them and finally quits with a throw of a @c |
|
|
|
traces them and finally quits with a throw of a @c |
|
|
|
atd::bad_exception. The only thing that may be different from |
|
|
|
std::bad_exception. You are also required to write a @c try @c |
|
|
|
project to project is, how tracing is done. The MRW C++ Class |
|
|
|
catch block around all in your @c main, so that you don't miss |
|
|
|
Library provides you with additional libraries you can link |
|
|
|
any exception. The only thing that may be different from project |
|
|
|
to. By linking to the library, you get an unexpected handler for |
|
|
|
to project is, how tracing is done. The MRW C++ Class Library |
|
|
|
free: You don't need to add a single line of code, just link to |
|
|
|
provides you with additional libraries you can link to. By |
|
|
|
one more library! The libraries differ in how tracing is done. |
|
|
|
linking to the library, you get an unexpected handler and an |
|
|
|
|
|
|
|
exception trace in the @c main for free: You don't need to add a |
|
|
|
|
|
|
|
single line of code, just link to one more library! The |
|
|
|
|
|
|
|
libraries differ in how tracing is done. |
|
|
|
|
|
|
|
|
|
|
|
The Implementation is done with a static instance of a class that |
|
|
|
The Implementation is done with a static instance of a class that |
|
|
|
sets the unexpected handler in the constructor. |
|
|
|
sets the unexpected handler in the constructor. |
|
|
@ -58,9 +66,10 @@ namespace mrw { |
|
|
|
@section trcstderr Trace using std::cerr |
|
|
|
@section trcstderr Trace using std::cerr |
|
|
|
|
|
|
|
|
|
|
|
If you link to the library @c libmrwexcstderr using a linker |
|
|
|
If you link to the library @c libmrwexcstderr using a linker |
|
|
|
option such as: @c -lmrwexcstderr, then an unexpected handler is |
|
|
|
option such as: @c -lmrwexcstderr, then an unexpected and a |
|
|
|
registered, that traces to the standard error stream @c |
|
|
|
terminate handler are registered, that trace to the standard |
|
|
|
std::cerr. You don't need to change a single line in your code! |
|
|
|
error stream @c std::cerr. You don't need to change a single |
|
|
|
|
|
|
|
line in your code! |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
//@{
|
|
|
|
//@{
|
|
|
|
|
|
|
|
|
|
|
@ -74,20 +83,22 @@ namespace mrw { |
|
|
|
void unexpected_stderr() { |
|
|
|
void unexpected_stderr() { |
|
|
|
std::cerr<<"UNEXPECTED EXCEPTION: ----------------------------"<<std::endl; |
|
|
|
std::cerr<<"UNEXPECTED EXCEPTION: ----------------------------"<<std::endl; |
|
|
|
try { |
|
|
|
try { |
|
|
|
|
|
|
|
StackTrace::createSymtable(); |
|
|
|
throw; |
|
|
|
throw; |
|
|
|
} catch (const mrw::exception& x) { |
|
|
|
} catch (const mrw::exception& x) { |
|
|
|
StackTrace::createSymtable(); |
|
|
|
|
|
|
|
std::cerr<<"---------- Reason:"<<std::endl |
|
|
|
std::cerr<<"---------- Reason:"<<std::endl |
|
|
|
<<x.what()<<std::endl |
|
|
|
<<x.what()<<std::endl |
|
|
|
<<"---------- Stack:"<<std::endl |
|
|
|
<<"---------- Stack:"<<std::endl |
|
|
|
<<x.stacktrace(); |
|
|
|
<<x.stacktrace(); |
|
|
|
} catch (const std::exception& x) { |
|
|
|
} catch (const std::exception& x) { |
|
|
|
|
|
|
|
std::string st((std::string)StackTrace()); |
|
|
|
std::cerr<<"---------- Reason:"<<std::endl |
|
|
|
std::cerr<<"---------- Reason:"<<std::endl |
|
|
|
<<x.what()<<std::endl |
|
|
|
<<x.what()<<std::endl |
|
|
|
<<"---------- Stack: **** not available ****"<<std::endl; |
|
|
|
<<"---------- Stack: "<<std::endl<<st; |
|
|
|
} catch (...) { |
|
|
|
} catch (...) { |
|
|
|
|
|
|
|
std::string st((std::string)StackTrace()); |
|
|
|
std::cerr<<"---------- Reason: **** not available ****"<<std::endl |
|
|
|
std::cerr<<"---------- Reason: **** not available ****"<<std::endl |
|
|
|
<<"---------- Stack: **** not available ****"<<std::endl; |
|
|
|
<<"---------- Stack:"<<std::endl<<st; |
|
|
|
} |
|
|
|
} |
|
|
|
std::cerr<<"-------------------------------------------------"<<std::endl; |
|
|
|
std::cerr<<"-------------------------------------------------"<<std::endl; |
|
|
|
throw std::bad_exception(); |
|
|
|
throw std::bad_exception(); |
|
|
@ -97,6 +108,37 @@ namespace mrw { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void unexpected_stderr() { |
|
|
|
void unexpected_stderr() { |
|
|
|
std::cerr<<"UNEXPECTED EXCEPTION: ----------------------------"<<std::endl; |
|
|
|
std::cerr<<"UNEXPECTED EXCEPTION: ----------------------------"<<std::endl; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
StackTrace::createSymtable(); |
|
|
|
|
|
|
|
throw; |
|
|
|
|
|
|
|
} catch (const mrw::exception& x) { |
|
|
|
|
|
|
|
std::cerr<<"---------- Reason:"<<std::endl |
|
|
|
|
|
|
|
<<x.what()<<std::endl |
|
|
|
|
|
|
|
<<"---------- Stack:"<<std::endl |
|
|
|
|
|
|
|
<<x.stacktrace(); |
|
|
|
|
|
|
|
} catch (const std::exception& x) { |
|
|
|
|
|
|
|
std::string st((std::string)StackTrace()); |
|
|
|
|
|
|
|
std::cerr<<"---------- Reason:"<<std::endl |
|
|
|
|
|
|
|
<<x.what()<<std::endl |
|
|
|
|
|
|
|
<<"---------- Stack:"<<std::endl<<st; |
|
|
|
|
|
|
|
} catch (...) { |
|
|
|
|
|
|
|
std::string st((std::string)StackTrace()); |
|
|
|
|
|
|
|
std::cerr<<"---------- Reason: **** not available ****"<<std::endl |
|
|
|
|
|
|
|
<<"---------- Stack:"<<std::endl<<st; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
std::cerr<<"-------------------------------------------------"<<std::endl; |
|
|
|
|
|
|
|
throw std::bad_exception(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @brief terminate handler, that traces to @c std::cerr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The terminate handler is installed automatically when you link |
|
|
|
|
|
|
|
to @c -lmrwexcstderr. The implementation of this terminate |
|
|
|
|
|
|
|
handler is as follows: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@code |
|
|
|
|
|
|
|
void terminate_stderr() { |
|
|
|
|
|
|
|
std::cerr<<"UNCAUGHT EXCEPTION: ----------------------------"<<std::endl; |
|
|
|
try { |
|
|
|
try { |
|
|
|
throw; |
|
|
|
throw; |
|
|
|
} catch (const mrw::exception& x) { |
|
|
|
} catch (const mrw::exception& x) { |
|
|
@ -114,7 +156,31 @@ namespace mrw { |
|
|
|
<<"---------- Stack: **** not available ****"<<std::endl; |
|
|
|
<<"---------- Stack: **** not available ****"<<std::endl; |
|
|
|
} |
|
|
|
} |
|
|
|
std::cerr<<"-------------------------------------------------"<<std::endl; |
|
|
|
std::cerr<<"-------------------------------------------------"<<std::endl; |
|
|
|
throw std::bad_exception(); |
|
|
|
exit(1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void terminate_stderr() { |
|
|
|
|
|
|
|
std::cerr<<"UNCAUGHT EXCEPTION: ----------------------------"<<std::endl; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
throw; |
|
|
|
|
|
|
|
} catch (const mrw::exception& x) { |
|
|
|
|
|
|
|
StackTrace::createSymtable(); |
|
|
|
|
|
|
|
std::cerr<<"---------- Reason:"<<std::endl |
|
|
|
|
|
|
|
<<x.what()<<std::endl |
|
|
|
|
|
|
|
<<"---------- Stack:"<<std::endl |
|
|
|
|
|
|
|
<<x.stacktrace(); |
|
|
|
|
|
|
|
} catch (const std::exception& x) { |
|
|
|
|
|
|
|
std::cerr<<"---------- Reason:"<<std::endl |
|
|
|
|
|
|
|
<<x.what()<<std::endl |
|
|
|
|
|
|
|
<<"---------- Stack: **** not available ****"<<std::endl; |
|
|
|
|
|
|
|
} catch (...) { |
|
|
|
|
|
|
|
std::cerr<<"---------- Reason: **** not available ****"<<std::endl |
|
|
|
|
|
|
|
<<"---------- Stack: **** not available ****"<<std::endl; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
std::cerr<<"-------------------------------------------------"<<std::endl; |
|
|
|
|
|
|
|
exit(1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//@}
|
|
|
|
//@}
|
|
|
@ -124,6 +190,7 @@ namespace mrw { |
|
|
|
public: |
|
|
|
public: |
|
|
|
AutoStackTrace() { |
|
|
|
AutoStackTrace() { |
|
|
|
std::set_unexpected(&mrw::unexpected_stderr); |
|
|
|
std::set_unexpected(&mrw::unexpected_stderr); |
|
|
|
|
|
|
|
std::set_terminate(&mrw::terminate_stderr); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|