C++ Library containing a lot of needful things: Stack Trace, Command Line Parser, Resource Handling, Configuration Files, Unix Command Execution, Directories, Regular Expressions, Tokenizer, Function Trace, Standard Extensions.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

181 lines
5.6 KiB

/** @file
$Id$
$Date$
$Author$
@copy © Marc Wäckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.7 2005/04/07 20:43:50 marc
docu corrected, new doxygen
Revision 1.6 2005/02/25 16:18:15 marc
now naming for the logger: "mrw.stacktrace" instead of simply "libmrw"
Revision 1.5 2005/01/28 12:13:11 marc
interference between group name StackTrace and class name StackTrace
Revision 1.4 2005/01/28 12:13:11 marc
interference between group name StackTrace and class name StackTrace
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<T>
- 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 <mrw/stacktrace.hpp>
#include <mrw/exception.hpp>
#include <exception>
#include <log4cxx/logger.h>
namespace mrw {
/** @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(). @see @ref AutoInitLog4cxx if you also want to
automatically configure @c log4cxx.
*/
//@{
/** @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("mrw.stacktrace")));
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("mrw.stacktrace")));
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("mrw.stacktrace")));
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("mrw.stacktrace")));
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;
}