X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fpbd%2Fstacktrace.h;h=40275fd536d4ff9c5bf58dff7b5e7caa972b12ec;hb=a459f96e38f569503e6d983808210d9d43a396ec;hp=c6da6ed79dbe69f85ceb73c268510542f449a95c;hpb=2e8f80e37a7d20deb3f138cd72c26f8c6de9d1ab;p=ardour.git diff --git a/libs/pbd/pbd/stacktrace.h b/libs/pbd/pbd/stacktrace.h index c6da6ed79d..40275fd536 100644 --- a/libs/pbd/pbd/stacktrace.h +++ b/libs/pbd/pbd/stacktrace.h @@ -20,10 +20,99 @@ #ifndef __libpbd_stacktrace_h__ #define __libpbd_stacktrace_h__ +#ifdef HAVE_WAFBUILD +#include "libpbd-config.h" +#endif + +#include #include +#include +#include + +#ifdef HAVE_EXECINFO +#include +#include +#endif namespace PBD { void stacktrace (std::ostream& out, int levels = 0); -} + void trace_twb(); + +template +class thing_with_backtrace +{ + public: + thing_with_backtrace () { + trace_twb(); +#ifdef HAVE_EXECINFO + allocation_backtrace = new void*[50]; + allocation_backtrace_size = backtrace (allocation_backtrace, 50); +#else + allocation_backtrace_size = 0; +#endif + Glib::Mutex::Lock lm (all_mutex); + all.push_back (this); + } + + thing_with_backtrace (const thing_with_backtrace& other) { + trace_twb(); +#ifdef HAVE_EXECINFO + allocation_backtrace = new void*[50]; + allocation_backtrace_size = backtrace (allocation_backtrace, 50); +#else + allocation_backtrace_size = 0; +#endif + Glib::Mutex::Lock lm (all_mutex); + all.push_back (this); + } + + ~thing_with_backtrace() { + if (allocation_backtrace_size) { + delete [] allocation_backtrace; + } + Glib::Mutex::Lock lm (all_mutex); + all.remove (this); + } + + thing_with_backtrace& operator= (const thing_with_backtrace& other) { + /* no copyable members */ + return *this; + } + + static void peek_a_boo (std::ostream& stream) { +#ifdef HAVE_EXECINFO + typename std::list*>::iterator x; + for (x = all.begin(); x != all.end(); ++x) { + char **strings; + size_t i; + + strings = backtrace_symbols ((*x)->allocation_backtrace, (*x)->allocation_backtrace_size); + + if (strings) { + stream << "--- ALLOCATED SHARED_PTR @ " << (*x) << std::endl; + for (i = 0; i < (*x)->allocation_backtrace_size && i < 50U; i++) { + stream << strings[i] << std::endl; + } + free (strings); + } + } +#else + stream << "execinfo not defined for this platform" << std::endl; +#endif + } + +private: + void** allocation_backtrace; + int allocation_backtrace_size; + static std::list* > all; + static Glib::StaticMutex all_mutex; +}; + +template std::list *> PBD::thing_with_backtrace::all; +template Glib::StaticMutex PBD::thing_with_backtrace::all_mutex = GLIBMM_STATIC_MUTEX_INIT; + +} // namespace PBD + + #endif /* __libpbd_stacktrace_h__ */