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.
200 lines
6.7 KiB
200 lines
6.7 KiB
/** @file |
|
|
|
$Id$ |
|
|
|
$Date$ |
|
$Author$ |
|
|
|
@copy © Marc Wäckerlin |
|
@license LGPL, see file <a href="license.html">COPYING</a> |
|
|
|
$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 |
|
|
|
Revision 1.3 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 <iostream> |
|
|
|
namespace mrw { |
|
|
|
/** @addtogroup StackTrace */ |
|
//@{ |
|
|
|
/** @defgroup AutoTrace Automated Unexpected and Terminate Handler |
|
with Stack Trace |
|
|
|
@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 |
|
mrw::exception, @c std::exception and all unknown exceptions, |
|
traces them and finally quits with a throw of a @c |
|
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. |
|
|
|
@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 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! |
|
*/ |
|
//@{ |
|
|
|
/** @brief unexpected handler, that traces to @c std::cerr |
|
|
|
The unexpected handler is installed automatically when you link |
|
to @c -lmrwexcstderr. The implementation of this unexpected |
|
handler is as follows: |
|
|
|
@code |
|
void unexpected_stderr() { |
|
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(); |
|
} |
|
@endcode |
|
|
|
*/ |
|
void unexpected_stderr() { |
|
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 { |
|
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); |
|
} |
|
@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); |
|
} |
|
|
|
//@} |
|
//@} |
|
|
|
class AutoStackTrace { |
|
public: |
|
AutoStackTrace() { |
|
std::set_unexpected(&mrw::unexpected_stderr); |
|
std::set_terminate(&mrw::terminate_stderr); |
|
} |
|
}; |
|
|
|
// initialize stack traces (load symbols) |
|
static AutoStackTrace _autoStackTrace; |
|
|
|
}
|
|
|