/** @file $Id: autofunctiontracelog4cxx.cxx,v 1.3 2005/04/14 19:12:18 marc Exp $ $Date: 2005/04/14 19:12:18 $ $Author: marc $ @copy © Marc Wäckerlin @license LGPL, see file COPYING 1 2 3 4 5 6 7 8 5678901234567890123456789012345678901234567890123456789012345678901234567890 */ #ifndef __GNUG__ #error GNU C++ Compiler is required for automatical function trace #endif #include #include #include #include #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<