From e5b6e06f837d8b0d3fdb89621d3a3703dc5a29a3 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 27 Nov 2009 17:30:39 +0000 Subject: get closer to carl's original boost shared_ptr debug idea by just tracking actual shared_ptr constructors+destructors git-svn-id: svn://localhost/ardour2/branches/3.0@6190 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/pbd/boost_debug.cc | 190 +++++++++++++++--------------------------------- 1 file changed, 57 insertions(+), 133 deletions(-) (limited to 'libs/pbd/boost_debug.cc') diff --git a/libs/pbd/boost_debug.cc b/libs/pbd/boost_debug.cc index ec58649d06..c9487197e1 100644 --- a/libs/pbd/boost_debug.cc +++ b/libs/pbd/boost_debug.cc @@ -36,27 +36,19 @@ class Backtrace { public: - Backtrace (int op, int use_count, void const* pn); + Backtrace (); std::ostream& print (std::ostream& str) const; - int use_count() const { return _use_count; } - void const* pn() const { return _pn; } - int op() const { return _op; } private: - int _op; - void const* _pn; void* trace[200]; size_t size; - int _use_count; }; std::ostream& operator<< (std::ostream& str, const Backtrace& bt) { return bt.print (str); } -Backtrace::Backtrace(int op, int uc, void const* pn) { - _op = op; - _pn = pn; - _use_count = uc; +Backtrace::Backtrace() +{ #ifdef HAVE_EXECINFO size = ::backtrace (trace, 200); #endif @@ -69,13 +61,11 @@ Backtrace::print (std::ostream& str) const 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++) { + for (i = 5; i < 5+18 && i < size; i++) { str << strings[i] << std::endl; } free (strings); @@ -89,16 +79,14 @@ struct BTPair { Backtrace* ref; Backtrace* rel; - long use_count; - - BTPair (Backtrace* bt, long uc) : ref (bt), rel (0), use_count (uc) {} + + BTPair (Backtrace* bt) : ref (bt), rel (0) {} ~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; @@ -108,8 +96,7 @@ std::ostream& operator<<(std::ostream& str, const BTPair& btp) { struct SPDebug { Backtrace* constructor; Backtrace* destructor; - std::vector others; - + SPDebug (Backtrace* c) : constructor (c), destructor (0) {} ~SPDebug () { delete constructor; @@ -119,79 +106,23 @@ struct SPDebug { std::ostream& operator<< (std::ostream& str, const SPDebug& spd) { - str << "Concerructor :" << std::endl; + str << "Constructor :" << 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::const_iterator x = spd.others.begin(); x != spd.others.end(); ++x) { - str << *x << std::endl; - } return str; } -typedef std::multimap TraceMap; -typedef std::map PointerMap; -typedef std::map PointerSet; - -static TraceMap traces; -static PointerMap interesting_pointers; -static PointerSet interesting_counters; -static Glib::StaticMutex the_lock; +typedef std::multimap PointerMap; +typedef std::map IPointerMap; using namespace std; -static void -trace_it (int op, void const* pn, void const* object, int use_count) -{ - Glib::Mutex::Lock guard (the_lock); - Backtrace* bt = new Backtrace (op, use_count, pn); - TraceMap::iterator i = traces.find (const_cast(object)); - - if (i == traces.end()) { - pair newpair; - newpair.first = object; - - if (op != 0) { - cerr << "SPDEBUG: non-constructor op without entry in trace map\n"; - return; - } - newpair.second = new SPDebug (bt); - traces.insert (newpair); - - } else { - 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 (); - } - } - } - } -} +PointerMap sptrs; +IPointerMap interesting_pointers; + +static Glib::StaticMutex the_lock; static bool is_interesting_object (void const* ptr) @@ -211,30 +142,57 @@ boost_debug_shared_ptr_mark_interesting (void* ptr, const char* type) Glib::Mutex::Lock guard (the_lock); pair newpair (ptr, type); interesting_pointers.insert (newpair); - cerr << "New interesting pointer: " << ptr << " type = " << type << endl; - for (PointerMap::iterator i = interesting_pointers.begin(); i != interesting_pointers.end(); ++i) { - cerr << "IP : " << i->first << " type = " << i->second << endl; - } - cerr << "is interesting ? " << is_interesting_object (ptr) << endl; } void -boost_debug_shared_ptr_show (ostream& str, void* ptr) +boost_debug_shared_ptr_operator_equals (void const *sp, void const *obj, int) { - Glib::Mutex::Lock guard (the_lock); - pair range; + if (is_interesting_object (obj)) { + cerr << "sp @ " << sp << " assigned\n"; + } +} - range = traces.equal_range (ptr); +void +boost_debug_shared_ptr_reset (void const *sp, void const *obj, int) +{ + if (is_interesting_object (obj)) { + cerr << "sp @ " << sp << " reset\n"; + } +} + +void +boost_debug_shared_ptr_destructor (void const *sp, void const *obj, int use_count) +{ + Glib::Mutex::Lock guard (the_lock); + PointerMap::iterator x = sptrs.find (sp); - if (range.first == traces.end()) { - str << "No shared_ptr debugging information found for " << ptr << endl; - return; + if (x != sptrs.end()) { + sptrs.erase (x); } +} +void +boost_debug_shared_ptr_constructor (void const *sp, void const *obj, int use_count) +{ + + if (is_interesting_object (obj)) { + Glib::Mutex::Lock guard (the_lock); + pair newpair; - str << "\n\n--------------------------------------------------------\ninfo for " << ptr << endl; + newpair.first = sp; + newpair.second = new SPDebug (new Backtrace()); + + sptrs.insert (newpair); + } +} - for (TraceMap::iterator i = range.first; i != range.second; ++i) { - str << *i->second << endl; +void +boost_debug_list_ptrs () +{ + Glib::Mutex::Lock guard (the_lock); + for (PointerMap::iterator x = sptrs.begin(); x != sptrs.end(); ++x) { + cerr << "Shared ptr @ " << x->first << " history: " + << *x->second + << endl; } } @@ -242,52 +200,18 @@ namespace boost { void sp_scalar_constructor_hook( void * object, std::size_t size, void * pn ) { - if (is_interesting_object (object)) { - cerr << "Interesting counter @ " << pn << endl; - pair newpair (pn, object); - interesting_counters.insert (newpair); - trace_it (0, pn, object, ((boost::detail::sp_counted_base*)pn)->use_count()); - - } } void sp_scalar_destructor_hook( void * object, std::size_t size, void * pn ) { - pair range; - long use_count = ((boost::detail::sp_counted_base*)pn)->use_count(); - - if (is_interesting_object (object)) { - trace_it (-1, pn, object, use_count); - } - - if (use_count == 1) { - // PointerMap::iterator p = interesting_pointers.find (object); - - //if (p != interesting_pointers.end()) { - // interesting_pointers.erase (p); - //} - } } 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; - trace_it (1, pn, i->second, use_count); - } } + 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; - if (use_count == 1) { - trace_it (2, pn, i->second, use_count); - } else { - trace_it (-1, pn, i->second, use_count); - } - } } void sp_array_constructor_hook(void * p) -- cgit v1.2.3