/** @file
$Id$
$Date$
$Author$
@copy © Marc Wäckerlin
@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
- new file header for all sources
- work around warning in mrw::auto
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
*/
#include
#include
#include
#include
namespace mrw {
/** @addtogroup StackTrace */
//@{
/** @addtogroup AutoTrace
@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 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
@note The configurator is not installed automatically. If you
want to trace e.g. on the console, you have to call @c
log4cxx::BasicConfigurator::configure(); as first statement in
your @c main().
*/
//@{
/** @brief unexpected handler, that traces using log4cxx
The unexpected handler is installed automatically when you link
to @c -lmrwexclog4cxx. The implementation of this unexpected
handler is as follows:
@code
void unexpected_log4cxx() {
log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("libmrw"));
logger->fatal("Unexpected 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);
}
throw std::bad_exception();
}
@endcode
*/
void unexpected_log4cxx() {
log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("libmrw"));
logger->fatal("Unexpected 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);
}
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);
}
//@}
//@}
class AutoStackTrace {
public:
AutoStackTrace() {
std::set_unexpected(&mrw::unexpected_log4cxx);
std::set_terminate(&mrw::terminate_log4cxx);
}
};
// initialize stack traces (load symbols)
static AutoStackTrace _autoStackTrace;
}