X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fpbd%2Fstacktrace.h;h=40275fd536d4ff9c5bf58dff7b5e7caa972b12ec;hb=a459f96e38f569503e6d983808210d9d43a396ec;hp=d7278bd35a545bbb22d46afc9a95553f0f0e418e;hpb=481f7c39655afec832ac10430dd61a3bb464aa58;p=ardour.git diff --git a/libs/pbd/pbd/stacktrace.h b/libs/pbd/pbd/stacktrace.h index d7278bd35a..40275fd536 100644 --- a/libs/pbd/pbd/stacktrace.h +++ b/libs/pbd/pbd/stacktrace.h @@ -1,10 +1,118 @@ +/* + Copyright (C) 2000-2007 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #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); -} + 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__ */