/** @file
$ Id : autofunctiontracelog4cxx . cpp , v 1.3 2005 / 04 / 14 19 : 12 : 18 marc Exp $
$ Date : 2005 / 04 / 14 19 : 12 : 18 $
$ Author : marc $
@ copy & copy ; Marc W & auml ; ckerlin
@ license LGPL , see file < a href = " license.html " > COPYING < / a >
1 2 3 4 5 6 7 8
5678901234567890123456789012345678901234567890123456789012345678901234567890
*/
# ifndef __GNUG__
# error GNU C++ Compiler is required for automatical function trace
# endif
# include <mrw/string.hpp>
# include <mrw/stacktrace.hpp>
# include <iostream>
# include <iomanip>
# if (__GNUC__==3 && __GNUC_MINOR__<4 || __GNUC__<3) \
& & defined ( _REENTRANT ) & & ! defined ( _MT )
# define _MT
# endif
// these are special built in functions of GNU Compiler Collection
extern " C " void __cyg_profile_func_enter ( void * , void * ) __attribute__ ( ( no_instrument_function ) ) ;
extern " C " void __cyg_profile_func_exit ( void * , void * ) __attribute__ ( ( no_instrument_function ) ) ;
namespace mrw {
// workaround doxygen problem:
// - the C++ compiler compiles the following code
// - doxygen ignores it
# ifndef LET_DOXYGEN_IGNORE_THIS // no matching class member found for
// int mrw::ThreadInfo::level()
struct ThreadInfo {
int level ;
bool recurse ;
} ;
# endif
# ifdef _MT
static __thread ThreadInfo info = { 0 , false } ;
# else
static ThreadInfo info = { 0 , false } ;
# endif
static bool mainPassed ( false ) ;
class Lock {
public :
Lock ( ) __attribute__ ( ( no_instrument_function ) ) ;
~ Lock ( ) __attribute__ ( ( no_instrument_function ) ) ;
} ;
// workaround doxygen problem:
// - the C++ compiler compiles the following code
// - doxygen ignores it
# ifndef LET_DOXYGEN_IGNORE_THIS // doxygen can't match with __attribute__ above
Lock : : Lock ( ) {
info . recurse = true ;
}
Lock : : ~ Lock ( ) {
info . recurse = false ;
}
# endif
}
extern " C " int main ( int , char * * ) ;
/** @addtogroup FunctionTrace */
//@{
/** @defgroup AutoFunctionTraceStdlog Automatic Function Trace to standard out for GNU g++
Same as @ ref AutoFunctionTrace , but traces to @ c stdlog .
If you link to the library @ c libmrwautofunctiontracestdlog using
a linker option such as : @ c - lmrwautofunctiontracestdlog and you
must enable the GNU Compiler Collection specific function trace
feature with compile and link option @ c - finstrument - functions
then you get an automatical function trace , that traces to @ c
stdlog . You don ' t need to change a single line in your code !
*/
//@{
//@}
//@}
extern " C " void __cyg_profile_func_enter ( void * this_fn , void * ) {
if ( ! mrw : : mainPassed )
if ( this_fn = = ( void * ) & : : main ) // not ANSI C++ conform...
mrw : : mainPassed = true ;
else
return ;
try {
if ( mrw : : info . recurse ) return ;
mrw : : Lock lock ;
{
static bool init ( mrw : : StackTrace : : createSymtable ( ) ) ;
if ( ! init ) return ;
mrw : : StackTrace : : CodePos pos ( mrw : : StackTrace : : translate ( this_fn ) ) ;
std : : clog < < std : : setw ( 2 + mrw : : info . level + + ) < < std : : setfill ( ' ' )
< < " \\ " < < pos . function < < " ( " < < pos . file < < ' : ' < < pos . line < < ' ) '
< < std : : endl ;
}
} catch ( . . . ) { }
}
extern " C " void __cyg_profile_func_exit ( void * this_fn , void * ) {
if ( ! mrw : : mainPassed )
return ;
else
if ( this_fn = = ( void * ) & : : main ) { // not ANSI C++ conform...
mrw : : mainPassed = false ;
return ;
}
try {
if ( mrw : : info . recurse | | mrw : : info . level = = 0 ) return ;
mrw : : Lock lock ;
{
mrw : : StackTrace : : CodePos pos ( mrw : : StackTrace : : translate ( this_fn ) ) ;
std : : clog < < std : : setw ( 2 + - - mrw : : info . level ) < < std : : setfill ( ' ' )
< < " / " < < pos . function < < " ( " < < pos . file < < ' : ' < < pos . line < < ' ) '
< < std : : endl ;
}
} catch ( . . . ) { }
}