added terminate handler (uncaught handler)
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user