diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-11-24 00:09:15 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-11-24 00:09:15 +0000 |
commit | 2b42f32531e5fb320569649c3f8bb49dcd507744 (patch) | |
tree | 1bef5a383e6fe3e5216fe3311105a22d9a608a12 /libs/pbd/boost_debug.cc | |
parent | 911fdb576e15283897cb7648d07f4ba14ec8f78e (diff) |
tweaks and tuneups of the boost debug stuff - still not done, need to track "scope" for grouping output properly
git-svn-id: svn://localhost/ardour2/branches/3.0@6163 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/pbd/boost_debug.cc')
-rw-r--r-- | libs/pbd/boost_debug.cc | 199 |
1 files changed, 108 insertions, 91 deletions
diff --git a/libs/pbd/boost_debug.cc b/libs/pbd/boost_debug.cc index eea0fc45e0..ec58649d06 100644 --- a/libs/pbd/boost_debug.cc +++ b/libs/pbd/boost_debug.cc @@ -18,28 +18,32 @@ */ +#include "libpbd-config.h" + +#ifdef HAVE_EXECINFO +#include <execinfo.h> +#endif + #include <stdlib.h> #include <iostream> #include <map> #include <set> -#include <list> +#include <vector> #include <glibmm/thread.h> #include <boost/shared_ptr.hpp> -#include "libpbd-config.h" - #include "pbd/stacktrace.h" class Backtrace { public: - Backtrace (int addsub, int use_count, void const* pn); + Backtrace (int op, int use_count, void const* pn); std::ostream& print (std::ostream& str) const; int use_count() const { return _use_count; } void const* pn() const { return _pn; } - int addsub() const { return _addsub; } + int op() const { return _op; } private: - int _addsub; + int _op; void const* _pn; void* trace[200]; size_t size; @@ -48,26 +52,28 @@ private: std::ostream& operator<< (std::ostream& str, const Backtrace& bt) { return bt.print (str); } -#ifdef HAVE_EXECINFO - -#include <execinfo.h> -Backtrace::Backtrace(int addsub, int uc, void const* pn) { - _addsub = addsub; +Backtrace::Backtrace(int op, int uc, void const* pn) { + _op = op; _pn = pn; _use_count = uc; +#ifdef HAVE_EXECINFO size = ::backtrace (trace, 200); +#endif } std::ostream& Backtrace::print (std::ostream& str) const { - char **strings; + char **strings = 0; size_t i; if (size) { + str << "BT generated with use count = " << _use_count << std::endl; + +#ifdef HAVE_EXECINFO strings = ::backtrace_symbols (trace, size); - +#endif if (strings) { for (i = 5; i < 5+12; i++) { str << strings[i] << std::endl; @@ -79,25 +85,57 @@ Backtrace::print (std::ostream& str) const return str; } -#else +struct BTPair { -Backtrace::Backtrace(int addsub, int uc, void const* sp) { - _addsub = addsub; - _pn = pn; - size = 0; - _use_count = uc; + Backtrace* ref; + Backtrace* rel; + long use_count; + + BTPair (Backtrace* bt, long uc) : ref (bt), rel (0), use_count (uc) {} + ~BTPair () { } + +}; + +std::ostream& operator<<(std::ostream& str, const BTPair& btp) { + str << "*********************************************\n"; + str << "@ " << btp.use_count << " Ref:\n"; + if (btp.ref) str << *btp.ref << std::endl; + str << "Rel:\n"; + if (btp.rel) str << *btp.rel << std::endl; + return str; } -std::ostream& -Backtrace::print (std::ostream& str) const +struct SPDebug { + Backtrace* constructor; + Backtrace* destructor; + std::vector<BTPair> others; + + SPDebug (Backtrace* c) : constructor (c), destructor (0) {} + ~SPDebug () { + delete constructor; + delete destructor; + } +}; + +std::ostream& operator<< (std::ostream& str, const SPDebug& spd) { - return str << "No shared ptr debugging available on this platform\n"; -} + str << "Concerructor :" << std::endl; + if (spd.constructor) { + str << *spd.constructor << std::endl; + } + str << "\nDestructor :" << std::endl; + if (spd.destructor) { + str << *spd.destructor << std::endl; + } + + for (std::vector<BTPair>::const_iterator x = spd.others.begin(); x != spd.others.end(); ++x) { + str << *x << std::endl; + } -#endif + return str; +} -typedef std::list<Backtrace*> BacktraceList; -typedef std::multimap<void const*,BacktraceList*> TraceMap; +typedef std::multimap<void const*,SPDebug*> TraceMap; typedef std::map<void const*,const char*> PointerMap; typedef std::map<void const*,void const*> PointerSet; @@ -109,22 +147,49 @@ static Glib::StaticMutex the_lock; using namespace std; static void -trace_it (int addsub, void const* pn, void const* object, int use_count) +trace_it (int op, void const* pn, void const* object, int use_count) { Glib::Mutex::Lock guard (the_lock); - Backtrace* bt = new Backtrace (addsub, use_count, pn); + Backtrace* bt = new Backtrace (op, use_count, pn); TraceMap::iterator i = traces.find (const_cast<void*>(object)); if (i == traces.end()) { - pair<void const *,BacktraceList*> newpair; + pair<void const *,SPDebug*> newpair; newpair.first = object; - newpair.second = new BacktraceList; - newpair.second->push_back (bt); + + if (op != 0) { + cerr << "SPDEBUG: non-constructor op without entry in trace map\n"; + return; + } + newpair.second = new SPDebug (bt); traces.insert (newpair); - cerr << "Start tracelist for " << object << endl; + } else { - i->second->push_back (bt); - cerr << "Extend tracelist for " << object << endl; + if (op == 0) { + cerr << "SPDEBUG: claimed constructor, but have range for this object\n"; + return; + } else if (op == 2) { + i->second->destructor = bt; + } else { + SPDebug* spd = i->second; + + if (spd->others.empty() || op == 1) { + spd->others.push_back (BTPair (bt, use_count)); + } else { + if (op == -1) { + if (spd->others.back().use_count == use_count-1) { + spd->others.back().rel = bt; + } else { + cerr << "********** FLoating REL\n"; + spd->others.push_back (BTPair (0, use_count)); + spd->others.back().rel = bt; + } + } else { + cerr << "SPDEBUG: illegal op number " << op << endl; + abort (); + } + } + } } } @@ -169,29 +234,7 @@ boost_debug_shared_ptr_show (ostream& str, void* ptr) str << "\n\n--------------------------------------------------------\ninfo for " << ptr << endl; for (TraceMap::iterator i = range.first; i != range.second; ++i) { - BacktraceList* bt; - bt = i->second; - for (BacktraceList::iterator x = bt->begin(); x != bt->end(); ++x) { - const char* op; - switch ((*x)->addsub()) { - case 0: - op = "CONST"; - break; - case -1: - op = "REL"; - break; - case 1: - op = "REF"; - break; - - case 2: - op = "DESTROY"; - break; - } - str << "\n**********************************************\n" - << "Back trace for " << op << " on " << ptr << " w/use_count = " << (*x)->use_count() << endl; - str << **x; - } + str << *i->second << endl; } } @@ -214,39 +257,9 @@ void sp_scalar_destructor_hook( void * object, std::size_t size, void * pn ) long use_count = ((boost::detail::sp_counted_base*)pn)->use_count(); if (is_interesting_object (object)) { - trace_it (2, pn, object, ((boost::detail::sp_counted_base*)pn)->use_count()); + trace_it (-1, pn, object, use_count); } - Glib::Mutex::Lock guard (the_lock); - - range = traces.equal_range (object); - - if (range.first != traces.end()) { - - for (TraceMap::iterator i = range.first; i != range.second; ++i) { - BacktraceList* btlist; - - btlist = i->second; - for (BacktraceList::iterator x = btlist->begin(); x != btlist->end(); ) { - if ((*x)->pn() == pn) { - delete *x; - x = btlist->erase (x); - } else { - ++x; - } - } - - if (use_count == 1) { - btlist->clear (); - delete btlist; - } - } - - if (use_count == 1) { - traces.erase (range.first, range.second); - } - } - if (use_count == 1) { // PointerMap::iterator p = interesting_pointers.find (object); @@ -260,7 +273,7 @@ void sp_counter_ref_hook (void* pn, long use_count) { PointerSet::iterator i = interesting_counters.find (pn); if (i != interesting_counters.end()) { - //cerr << "UC for " << pn << " inc from " << use_count << endl; + // cerr << "UC for " << pn << " inc from " << use_count << endl; trace_it (1, pn, i->second, use_count); } } @@ -268,8 +281,12 @@ void sp_counter_release_hook (void* pn, long use_count) { PointerSet::iterator i = interesting_counters.find (pn); if (i != interesting_counters.end()) { - cerr << "UC for " << pn << " dec from " << use_count << endl; - trace_it (-1, pn, i->second, use_count); + // cerr << "UC for " << pn << " dec from " << use_count << endl; + if (use_count == 1) { + trace_it (2, pn, i->second, use_count); + } else { + trace_it (-1, pn, i->second, use_count); + } } } |