/*
- Copyright (C) 2009 Paul Davis
- From an idea by Carl Hetherington.
-
- 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.
-
-*/
+ * Copyright (C) 2009-2018 Paul Davis <paul@linuxaudiosystems.com>
+ * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
#include "libpbd-config.h"
#include <map>
#include <set>
#include <vector>
-#include <glibmm/thread.h>
+#include <glibmm/threads.h>
#include <boost/shared_ptr.hpp>
#include "pbd/stacktrace.h"
+#include "pbd/boost_debug.h"
class Backtrace {
public:
- Backtrace ();
- std::ostream& print (std::ostream& str) const;
+ Backtrace ();
+ std::ostream& print (std::ostream& str) const;
private:
- void* trace[200];
- size_t size;
+ void* trace[200];
+ size_t size;
};
std::ostream& operator<< (std::ostream& str, const Backtrace& bt) { return bt.print (str); }
-
-Backtrace::Backtrace()
-{
+Backtrace::Backtrace()
+{
#ifdef HAVE_EXECINFO
size = ::backtrace (trace, 200);
#endif
if (size) {
#ifdef HAVE_EXECINFO
strings = ::backtrace_symbols (trace, size);
-#endif
+#endif
if (strings) {
for (i = 3; i < 5+18 && i < size; i++) {
str << strings[i] << std::endl;
return str;
}
-struct BTPair {
-
- Backtrace* ref;
- Backtrace* rel;
+struct BTPair {
- BTPair (Backtrace* bt) : ref (bt), rel (0) {}
- ~BTPair () { }
+ Backtrace* ref;
+ Backtrace* rel;
+ BTPair (Backtrace* bt) : ref (bt), rel (0) {}
+ ~BTPair () { }
};
std::ostream& operator<<(std::ostream& str, const BTPair& btp) {
return str;
}
-struct SPDebug {
- Backtrace* constructor;
- Backtrace* destructor;
-
- SPDebug (Backtrace* c) : constructor (c), destructor (0) {}
- ~SPDebug () {
- delete constructor;
- delete destructor;
- }
+struct SPDebug {
+ Backtrace* constructor;
+ Backtrace* destructor;
+
+ SPDebug (Backtrace* c) : constructor (c), destructor (0) {}
+ ~SPDebug () {
+ delete constructor;
+ delete destructor;
+ }
};
std::ostream& operator<< (std::ostream& str, const SPDebug& spd)
return str;
}
-typedef std::multimap<void const*,SPDebug*> PointerMap;
-typedef std::map<void const*,const char*> IPointerMap;
+typedef std::multimap<volatile void const*,SPDebug*> PointerMap;
+typedef std::map<volatile void const*,const char*> IPointerMap;
using namespace std;
static PointerMap* _sptrs;
-PointerMap& sptrs() {
- if (_sptrs == 0) {
- _sptrs = new PointerMap;
- }
- return *_sptrs;
+PointerMap& sptrs()
+{
+ if (_sptrs == 0) {
+ _sptrs = new PointerMap;
+ }
+ return *_sptrs;
}
static IPointerMap* _interesting_pointers;
-IPointerMap& interesting_pointers() {
- if (_interesting_pointers == 0) {
- _interesting_pointers = new IPointerMap;
- }
- return *_interesting_pointers;
+IPointerMap& interesting_pointers()
+{
+ if (_interesting_pointers == 0) {
+ _interesting_pointers = new IPointerMap;
+ }
+ return *_interesting_pointers;
}
-static Glib::Mutex* _the_lock;
-static Glib::Mutex& the_lock() {
- if (_the_lock == 0) {
- _the_lock = new Glib::Mutex;
- }
- return *_the_lock;
+static Glib::Threads::Mutex* _the_lock;
+static Glib::Threads::Mutex& the_lock()
+{
+ if (_the_lock == 0) {
+ _the_lock = new Glib::Threads::Mutex;
+ }
+ return *_the_lock;
}
static bool
-is_interesting_object (void const* ptr)
+is_interesting_object (volatile void const* ptr)
{
if (ptr == 0) {
return false;
}
-
+
return interesting_pointers().find (ptr) != interesting_pointers().end();
}
void
boost_debug_shared_ptr_mark_interesting (void* ptr, const char* type)
{
- Glib::Mutex::Lock guard (the_lock());
- pair<void*,const char*> newpair (ptr, type);
+ Glib::Threads::Mutex::Lock guard (the_lock());
+ pair<void*,const char*> newpair (ptr, type);
interesting_pointers().insert (newpair);
if (debug_out) {
cerr << "Interesting object @ " << ptr << " of type " << type << endl;
return;
}
- Glib::Mutex::Lock guard (the_lock());
+ Glib::Threads::Mutex::Lock guard (the_lock());
if (is_interesting_object (old_obj) || is_interesting_object (obj)) {
if (debug_out) {
if (is_interesting_object (old_obj)) {
if (debug_out) {
- cerr << "\tlost old sp @ " << sp << " for " << old_obj << " UC = " << old_use_count << " now for " << obj << " UC = " << new_use_count
- << " (total sp's = " << sptrs().size() << ')' << endl;
+ cerr << "\tlost old sp @ " << sp << " for " << old_obj << " UC = " << old_use_count << " now for " << obj << " UC = " << new_use_count
+ << " (total sp's = " << sptrs().size() << ')' << endl;
}
PointerMap::iterator x = sptrs().find (sp);
-
+
if (x != sptrs().end()) {
sptrs().erase (x);
if (debug_out) {
- cerr << "\tRemoved (by assigment) sp for " << old_obj << " @ " << sp << " UC = " << old_use_count << " (total sp's = " << sptrs().size() << ')' << endl;
+ cerr << "\tRemoved (by assignment) sp for " << old_obj << " @ " << sp << " UC = " << old_use_count << " (total sp's = " << sptrs().size() << ')' << endl;
}
}
}
newpair.second = new SPDebug (new Backtrace());
sptrs().insert (newpair);
-
+
if (debug_out) {
- cerr << "assignment created sp for " << obj << " @ " << sp << " used to point to " << old_obj << " UC = " << old_use_count
- << " UC = " << new_use_count
- << " (total sp's = " << sptrs().size() << ')' << endl;
+ cerr << "assignment created sp for " << obj << " @ " << sp << " used to point to " << old_obj << " UC = " << old_use_count
+ << " UC = " << new_use_count
+ << " (total sp's = " << sptrs().size() << ')' << endl;
cerr << *newpair.second << endl;
}
- }
+ }
}
void
return;
}
- Glib::Mutex::Lock guard (the_lock());
+ Glib::Threads::Mutex::Lock guard (the_lock());
if (is_interesting_object (old_obj) || is_interesting_object (obj)) {
if (debug_out) {
if (is_interesting_object (old_obj)) {
if (debug_out) {
- cerr << "\tlost old sp @ " << sp << " for " << old_obj << " UC = " << old_use_count << " now for " << obj << " UC = " << new_use_count
- << " (total sp's = " << sptrs().size() << ')' << endl;
+ cerr << "\tlost old sp @ " << sp << " for " << old_obj << " UC = " << old_use_count << " now for " << obj << " UC = " << new_use_count
+ << " (total sp's = " << sptrs().size() << ')' << endl;
}
PointerMap::iterator x = sptrs().find (sp);
-
+
if (x != sptrs().end()) {
sptrs().erase (x);
if (debug_out) {
newpair.second = new SPDebug (new Backtrace());
sptrs().insert (newpair);
-
+
if (debug_out) {
- cerr << "reset created sp for " << obj << " @ " << sp << " used to point to " << old_obj << " UC = " << old_use_count
- << " UC = " << new_use_count
- << " (total sp's = " << sptrs().size() << ')' << endl;
+ cerr << "reset created sp for " << obj << " @ " << sp << " used to point to " << old_obj << " UC = " << old_use_count
+ << " UC = " << new_use_count
+ << " (total sp's = " << sptrs().size() << ')' << endl;
cerr << *newpair.second << endl;
}
- }
+ }
}
void
-boost_debug_shared_ptr_destructor (void const *sp, void const *obj, int use_count)
+boost_debug_shared_ptr_destructor (void const *sp, volatile void const *obj, int use_count)
{
- Glib::Mutex::Lock guard (the_lock());
+ Glib::Threads::Mutex::Lock guard (the_lock());
PointerMap::iterator x = sptrs().find (sp);
if (x != sptrs().end()) {
}
void
-boost_debug_shared_ptr_constructor (void const *sp, void const *obj, int use_count)
+boost_debug_shared_ptr_constructor (void const *sp, volatile void const *obj, int use_count)
{
if (is_interesting_object (obj)) {
- Glib::Mutex::Lock guard (the_lock());
+ Glib::Threads::Mutex::Lock guard (the_lock());
pair<void const*, SPDebug*> newpair;
newpair.first = sp;
void
boost_debug_count_ptrs ()
{
- Glib::Mutex::Lock guard (the_lock());
+ Glib::Threads::Mutex::Lock guard (the_lock());
// cerr << "Tracking " << interesting_pointers().size() << " interesting objects with " << sptrs().size () << " shared ptrs\n";
}
void
boost_debug_list_ptrs ()
{
- Glib::Mutex::Lock guard (the_lock());
+ Glib::Threads::Mutex::Lock guard (the_lock());
if (sptrs().empty()) {
cerr << "There are no dangling shared ptrs\n";
{
}
-void sp_counter_release_hook (void* /*pn*/, long /*use_count*/)
+void sp_counter_release_hook (void* /*pn*/, long /*use_count*/)
{
}