/** @file
$ Id $
$ Date $
$ Author $
@ copy & copy ; Marc W & auml ; ckerlin
@ license LGPL , see file < a href = " license.html " > COPYING < / a >
$ Log $
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 grpStackTrace */
//@{
/** @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 ( " 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 ( )
+ " \n Stack:+ \n " + x . stacktrace ( ) ) ;
} catch ( const std : : exception & x ) {
logger - > fatal ( std : : string ( " Reason: \n " ) + x . what ( )
+ " \n Stack: \n " + st ) ;
} catch ( . . . ) {
logger - > fatal ( std : : string ( " Reason: **** not available **** " )
+ " \n Stack: \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 ( )
+ " \n Stack: \n " + x . stacktrace ( ) ) ;
} catch ( const std : : exception & x ) {
logger - > fatal ( std : : string ( " Reason: \n " ) + x . what ( )
+ " \n Stack: \n " + st ) ;
} catch ( . . . ) {
logger - > fatal ( std : : string ( " Reason: **** not available **** " )
+ " \n Stack: \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 ( )
+ " \n Stack:+ \n " + x . stacktrace ( ) ) ;
} catch ( const std : : exception & x ) {
logger - > fatal ( std : : string ( " Reason: \n " ) + x . what ( )
+ " \n Stack: \n " + st ) ;
} catch ( . . . ) {
logger - > fatal ( std : : string ( " Reason: **** not available **** " )
+ " \n Stack: \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 ( )
+ " \n Stack: \n " + x . stacktrace ( ) ) ;
} catch ( const std : : exception & x ) {
logger - > fatal ( std : : string ( " Reason: \n " ) + x . what ( )
+ " \n Stack: \n " + st ) ;
} catch ( . . . ) {
logger - > fatal ( std : : string ( " Reason: **** not available **** " )
+ " \n Stack: \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 ;
}