added terminate handler (uncaught handler)

master
Marc Wäckerlin 20 years ago
parent eee6f1b028
commit 4e91c2fe11
  1. 63
      mrw/autostacktracelog4cxx.cpp
  2. 103
      mrw/autostacktracestderr.cpp

@ -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.3 2005/01/28 07:42:23 marc
added terminate handler (uncaught handler)
Revision 1.2 2004/08/28 16:21:25 marc Revision 1.2 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw) mrw-c++-0.92 (mrw)
- new file: version.cpp - new file: version.cpp
@ -38,9 +41,10 @@ namespace mrw {
@section trclog4cxx Trace using the log4cxx Library @section trclog4cxx Trace using the log4cxx Library
If you link to the library @c libmrwexclog4cxx using a linker If you link to the library @c libmrwexclog4cxx using a linker
option such as: @c -lmrwexclog4cxx, then an unexpected handler option such as: @c -lmrwexclog4cxx, then an unexpected and a
is registered, that traces a fatal error using the log4cxx terminate handler are registered, that trace a fatal error using
library. You don't need to change a single line in your code! the log4cxx library. You don't need to change a single line in
your code!
The log4cxx library is located at: The log4cxx library is located at:
- http://logging.apache.org/log4cxx - http://logging.apache.org/log4cxx
@ -90,7 +94,7 @@ namespace mrw {
throw; throw;
} catch (const mrw::exception& x) { } catch (const mrw::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what() logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack:+\n"+x.stacktrace()); +"\nStack:\n"+x.stacktrace());
} catch (const std::exception& x) { } catch (const std::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what() logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack:\n"+st); +"\nStack:\n"+st);
@ -101,6 +105,56 @@ namespace mrw {
throw std::bad_exception(); throw std::bad_exception();
} }
/** @brief terminate handler, that traces using log4cxx
The terminate handler is installed automatically when you link
to @c -lmrwexclog4cxx. The implementation of this terminate
handler is as follows:
@code
void terminate_log4cxx() {
log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("libmrw"));
logger->fatal("Uncaught Exception", __FILE__, __LINE__);
StackTrace::createSymtable();
std::string st((std::string)StackTrace());
try {
throw;
exit(0);
} catch (const mrw::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack:+\n"+x.stacktrace());
} catch (const std::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack:\n"+st);
} catch (...) {
logger->fatal(std::string("Reason: **** not available ****")
+"\nStack:\n"+st);
}
exit(1);
}
@endcode
*/
void terminate_log4cxx() {
log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("libmrw"));
logger->fatal("Uncaught Exception", __FILE__, __LINE__);
StackTrace::createSymtable();
std::string st((std::string)StackTrace());
try {
throw;
} catch (const mrw::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack:\n"+x.stacktrace());
} catch (const std::exception& x) {
logger->fatal(std::string("Reason:\n")+x.what()
+"\nStack:\n"+st);
} catch (...) {
logger->fatal(std::string("Reason: **** not available ****")
+"\nStack:\n"+st);
}
exit(1);
}
//@} //@}
//@} //@}
@ -108,6 +162,7 @@ namespace mrw {
public: public:
AutoStackTrace() { AutoStackTrace() {
std::set_unexpected(&mrw::unexpected_log4cxx); std::set_unexpected(&mrw::unexpected_log4cxx);
std::set_terminate(&mrw::terminate_log4cxx);
} }
}; };

@ -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);
} }
}; };

Loading…
Cancel
Save