From 4e91c2fe1104c6a5b2419984ac7ad415d5a26733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Fri, 28 Jan 2005 07:42:23 +0000 Subject: [PATCH] added terminate handler (uncaught handler) --- mrw/autostacktracelog4cxx.cpp | 63 +++++++++++++++++++-- mrw/autostacktracestderr.cpp | 103 ++++++++++++++++++++++++++++------ 2 files changed, 144 insertions(+), 22 deletions(-) diff --git a/mrw/autostacktracelog4cxx.cpp b/mrw/autostacktracelog4cxx.cpp index b9d05e8..1228dc5 100644 --- a/mrw/autostacktracelog4cxx.cpp +++ b/mrw/autostacktracelog4cxx.cpp @@ -9,6 +9,9 @@ @license LGPL, see file COPYING $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 mrw-c++-0.92 (mrw) - new file: version.cpp @@ -38,9 +41,10 @@ namespace mrw { @section trclog4cxx Trace using the log4cxx Library If you link to the library @c libmrwexclog4cxx using a linker - option such as: @c -lmrwexclog4cxx, then an unexpected handler - is registered, that traces a fatal error using the log4cxx - library. You don't need to change a single line in your code! + option such as: @c -lmrwexclog4cxx, then an unexpected and a + terminate handler are registered, that trace a fatal error using + the log4cxx library. You don't need to change a single line in + your code! The log4cxx library is located at: - http://logging.apache.org/log4cxx @@ -90,7 +94,7 @@ namespace mrw { throw; } catch (const mrw::exception& x) { logger->fatal(std::string("Reason:\n")+x.what() - +"\nStack:+\n"+x.stacktrace()); + +"\nStack:\n"+x.stacktrace()); } catch (const std::exception& x) { logger->fatal(std::string("Reason:\n")+x.what() +"\nStack:\n"+st); @@ -101,6 +105,56 @@ namespace mrw { 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: AutoStackTrace() { std::set_unexpected(&mrw::unexpected_log4cxx); + std::set_terminate(&mrw::terminate_log4cxx); } }; diff --git a/mrw/autostacktracestderr.cpp b/mrw/autostacktracestderr.cpp index 5527d2c..ca04ee1 100644 --- a/mrw/autostacktracestderr.cpp +++ b/mrw/autostacktracestderr.cpp @@ -9,6 +9,9 @@ @license LGPL, see file COPYING $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 no newline at the end of stack trace @@ -36,21 +39,26 @@ namespace mrw { /** @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 - do all the repetitive work for you. + @brief Don't care about the unexpected handler, don't care about + 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 - unexpected handler, that rethrows, catches the @c + For all your programs it is recommended to implement an + identical unexpected handler, that rethrows, catches the @c mrw::exception, @c std::exception and all unknown exceptions, traces them and finally quits with a throw of a @c - atd::bad_exception. The only thing that may be different from - project to project is, how tracing is done. The MRW C++ Class - Library provides you with additional libraries you can link - to. By linking to the library, you get an unexpected handler 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. + std::bad_exception. You are also required to write a @c try @c + catch block around all in your @c main, so that you don't miss + any exception. The only thing that may be different from project + to project is, how tracing is done. The MRW C++ Class Library + provides you with additional libraries you can link to. By + 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 sets the unexpected handler in the constructor. @@ -58,9 +66,10 @@ namespace mrw { @section trcstderr Trace using std::cerr If you link to the library @c libmrwexcstderr using a linker - option such as: @c -lmrwexcstderr, then an unexpected handler is - registered, that traces to the standard error stream @c - std::cerr. You don't need to change a single line in your code! + option such as: @c -lmrwexcstderr, then an unexpected and a + terminate handler are registered, that trace to the standard + 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() { std::cerr<<"UNEXPECTED EXCEPTION: ----------------------------"<