This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
Improved pretty printing for smart pointers
- From: Michael Marte <informarte at freenet dot de>
- To: gdb at sourceware dot org
- Date: Tue, 16 Apr 2013 12:35:40 +0200
- Subject: Improved pretty printing for smart pointers
Hello *,
I found the pretty printers for std::shared_ptr, std::weak_ptr and
std::unique_ptr (as provided by
svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python) not sufficient for
daily use as they only generate a description (including the address of
the pointee) but do not pretty print the pointee itself. This behaviour
implies that one has to copy the address of the pointee, cast it to the
pointee's type, and dereference the result. To improve on the current
state of affairs, I improved the pretty printers to generate children.
For std::shared_ptr and std::weak_ptr, three children are generated,
namely "Use count", "Weak count", and "Managed value". For
std::unique_ptr, one child is generated, namely "Managed value". Using
this solution with an IDE like kdevelop or Eclipse CTD, it only needs
two clicks to see the value managed by a smart pointer.
I attached my patch in the hope that you will find it interesting and
that it will be integrated into your suite of GCC STL pretty printers.
Best regards,
Michael Marte
Index: libstdcxx/v6/printers.py
===================================================================
--- libstdcxx/v6/printers.py (revision 197410)
+++ libstdcxx/v6/printers.py (working copy)
@@ -57,10 +57,35 @@
class SharedPointerPrinter:
"Print a shared_ptr or weak_ptr"
+ class _iterator:
+ def __init__(self, sharedPointer):
+ self.sharedPointer = sharedPointer
+ self.managedValue = sharedPointer.val['_M_ptr']
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.managedValue == 0:
+ raise StopIteration
+ self.count = self.count + 1
+ if (self.count == 1):
+ return ('Use count', self.sharedPointer.val['_M_refcount']['_M_pi']['_M_use_count'])
+ elif (self.count == 2):
+ return ('Weak count', self.sharedPointer.val['_M_refcount']['_M_pi']['_M_weak_count'] - 1)
+ elif (self.count == 3):
+ return ('Managed value', self.managedValue)
+ else:
+ raise StopIteration
+
def __init__ (self, typename, val):
self.typename = typename
self.val = val
+ def children (self):
+ return self._iterator(self)
+
def to_string (self):
state = 'empty'
refcounts = self.val['_M_refcount']['_M_pi']
@@ -68,17 +93,35 @@
usecount = refcounts['_M_use_count']
weakcount = refcounts['_M_weak_count']
if usecount == 0:
- state = 'expired, weak %d' % weakcount
+ state = 'expired, weakcount %d' % weakcount
else:
- state = 'count %d, weak %d' % (usecount, weakcount - 1)
- return '%s (%s) %s' % (self.typename, state, self.val['_M_ptr'])
+ state = 'usecount %d, weakcount %d' % (usecount, weakcount - 1)
+ return '%s (%s) to %s' % (self.typename, state, self.val['_M_ptr'])
class UniquePointerPrinter:
"Print a unique_ptr"
+ class _iterator:
+ def __init__(self, uniquePointer):
+ self.uniquePointer = uniquePointer
+ self.managedValue = uniquePointer.val['_M_t']['_M_head_impl']
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.managedValue == 0 or self.count == 1:
+ raise StopIteration
+ self.count = self.count + 1
+ return ('Managed value', self.managedValue)
+
def __init__ (self, typename, val):
self.val = val
+ def children (self):
+ return self._iterator(self)
+
def to_string (self):
v = self.val['_M_t']['_M_head_impl']
return ('std::unique_ptr<%s> containing %s' % (str(v.type.target()),