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.
 
 
 
 
 

105 lines
3.6 KiB

#include <mrw/stacktrace.hpp>
#include <mrw/exception.hpp>
#include <exception>
#include <iostream>
namespace mrw {
/** @addtogroup StackTrace */
//@{
/** @defgroup AutoTrace Automated Unexpected Handler with Stack Trace
@brief Don't care about the unexpected handler, 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
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.
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 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!
*/
//@{
/** @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 {
throw;
} catch (const mrw::exception& x) {
StackTrace::createSymtable();
std::cerr<<"---------- Reason:"<<std::endl
<<x.what()<<std::endl
<<"---------- Stack:"<<std::endl
<<x.stacktrace()<<std::endl;
} 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;
throw std::bad_exception();
}
@endcode
*/
void unexpected_stderr() {
std::cerr<<"UNEXPECTED 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()<<std::endl;
} 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;
throw std::bad_exception();
}
//@}
//@}
class AutoStackTrace {
public:
AutoStackTrace() {
std::set_unexpected(&mrw::unexpected_stderr);
}
};
// initialize stack traces (load symbols)
static AutoStackTrace _autoStackTrace;
}