Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class
On Thu, 28 Sept 2023, 21:38 Tom Tromey, wrote: > Jonathan> I've pushed the changes I wanted to make, so you'll have to > rebase > Jonathan> your patches now, sorry. > > No problem. I rebased & re-tested them. > I can send a v2 if you want to double-check (only this large patch > required any changes), or just go ahead. Let me know. > Just go ahead, the changes are all straightforward so if the tests still pass, you can push it. I may not be able to push until Monday. > > Tom >
Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class
Jonathan> I've pushed the changes I wanted to make, so you'll have to rebase Jonathan> your patches now, sorry. No problem. I rebased & re-tested them. I can send a v2 if you want to double-check (only this large patch required any changes), or just go ahead. Let me know. I may not be able to push until Monday. Tom
Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class
On Thu, 28 Sept 2023 at 18:50, Tom Tromey via Libstdc++ wrote: > > GDB 14 will add a new ValuePrinter tag class that will be used to > signal that pretty-printers will agree to the "extension protocol" -- > essentially that they will follow some simple namespace rules, so that > GDB can add new methods over time. > > A couple new methods have already been added to GDB, to support DAP. > While I haven't implemented these for any libstdc++ printers yet, this > patch makes the basic conversion: printers derive from > gdb.ValuePrinter if it is available, and all "non-standard" (that is, > not specified by GDB) members of the various value-printing classes > are renamed to have a leading underscore. OK, thanks. I've pushed the changes I wanted to make, so you'll have to rebase your patches now, sorry. > --- > libstdc++-v3/python/libstdcxx/v6/printers.py | 1201 +- > 1 file changed, 605 insertions(+), 596 deletions(-) > > diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py > b/libstdc++-v3/python/libstdcxx/v6/printers.py > index d60c8003a63..bbc4375541f 100644 > --- a/libstdc++-v3/python/libstdcxx/v6/printers.py > +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py > @@ -97,6 +97,12 @@ try: > except ImportError: > pass > > +# Use the base class if available. > +if hasattr(gdb, 'ValuePrinter'): > +printer_base = gdb.ValuePrinter > +else: > +printer_base = object > + > # Starting with the type ORIG, search for the member type NAME. This > # handles searching upward through superclasses. This is needed to > # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615. > @@ -241,43 +247,43 @@ class SmartPtrIterator(Iterator): > "An iterator for smart pointer types with a single 'child' value" > > def __init__(self, val): > -self.val = val > +self._val = val > > def __iter__(self): > return self > > def __next__(self): > -if self.val is None: > +if self._val is None: > raise StopIteration > -self.val, val = None, self.val > +self._val, val = None, self._val > return ('get()', val) > > > -class SharedPointerPrinter: > +class SharedPointerPrinter(printer_base): > "Print a shared_ptr, weak_ptr, atomic, or atomic" > > def __init__(self, typename, val): > -self.typename = strip_versioned_namespace(typename) > -self.val = val > -self.pointer = val['_M_ptr'] > +self._typename = strip_versioned_namespace(typename) > +self._val = val > +self._pointer = val['_M_ptr'] > > def children(self): > -return SmartPtrIterator(self.pointer) > +return SmartPtrIterator(self._pointer) > > # Return the _Sp_counted_base<>* that holds the refcounts. > def _get_refcounts(self): > -if self.typename == 'std::atomic': > +if self._typename == 'std::atomic': > # A tagged pointer is stored as uintptr_t. > -ptr_val = self.val['_M_refcount']['_M_val']['_M_i'] > +ptr_val = self._val['_M_refcount']['_M_val']['_M_i'] > ptr_val = ptr_val - (ptr_val % 2) # clear lock bit > -ptr_type = find_type(self.val['_M_refcount'].type, 'pointer') > +ptr_type = find_type(self._val['_M_refcount'].type, 'pointer') > return ptr_val.cast(ptr_type) > -return self.val['_M_refcount']['_M_pi'] > +return self._val['_M_refcount']['_M_pi'] > > def to_string(self): > state = 'empty' > refcounts = self._get_refcounts() > -targ = self.val.type.template_argument(0) > +targ = self._val.type.template_argument(0) > targ = strip_versioned_namespace(str(targ)) > > if refcounts != 0: > @@ -288,7 +294,7 @@ class SharedPointerPrinter: > else: > state = 'use count %d, weak count %d' % ( > usecount, weakcount - 1) > -return '%s<%s> (%s)' % (self.typename, targ, state) > +return '%s<%s> (%s)' % (self._typename, targ, state) > > > def _tuple_impl_get(val): > @@ -347,17 +353,17 @@ def unique_ptr_get(val): > return tuple_get(0, tuple_member) > > > -class UniquePointerPrinter: > +class UniquePointerPrinter(printer_base): > "Print a unique_ptr" > > def __init__(self, typename, val): > -self.val = val > +self._val = val > > def children(self): > -return SmartPtrIterator(unique_ptr_get(self.val)) > +return SmartPtrIterator(unique_ptr_get(self._val)) > > def to_string(self): > -return ('std::unique_ptr<%s>' % > (str(self.val.type.template_argument(0 > +return ('std::unique_ptr<%s>' % > (str(self._val.type.template_argument(0 > > > def get_value_from_aligned_membuf(buf, valtype): > @@ -381,55 +387,56 @@ def get_value_from_list_node(node): > raise ValueError("Unsupported implementation for %s" % str(node.type)) > > > -class StdListPrinter:
[PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class
GDB 14 will add a new ValuePrinter tag class that will be used to signal that pretty-printers will agree to the "extension protocol" -- essentially that they will follow some simple namespace rules, so that GDB can add new methods over time. A couple new methods have already been added to GDB, to support DAP. While I haven't implemented these for any libstdc++ printers yet, this patch makes the basic conversion: printers derive from gdb.ValuePrinter if it is available, and all "non-standard" (that is, not specified by GDB) members of the various value-printing classes are renamed to have a leading underscore. --- libstdc++-v3/python/libstdcxx/v6/printers.py | 1201 +- 1 file changed, 605 insertions(+), 596 deletions(-) diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index d60c8003a63..bbc4375541f 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -97,6 +97,12 @@ try: except ImportError: pass +# Use the base class if available. +if hasattr(gdb, 'ValuePrinter'): +printer_base = gdb.ValuePrinter +else: +printer_base = object + # Starting with the type ORIG, search for the member type NAME. This # handles searching upward through superclasses. This is needed to # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615. @@ -241,43 +247,43 @@ class SmartPtrIterator(Iterator): "An iterator for smart pointer types with a single 'child' value" def __init__(self, val): -self.val = val +self._val = val def __iter__(self): return self def __next__(self): -if self.val is None: +if self._val is None: raise StopIteration -self.val, val = None, self.val +self._val, val = None, self._val return ('get()', val) -class SharedPointerPrinter: +class SharedPointerPrinter(printer_base): "Print a shared_ptr, weak_ptr, atomic, or atomic" def __init__(self, typename, val): -self.typename = strip_versioned_namespace(typename) -self.val = val -self.pointer = val['_M_ptr'] +self._typename = strip_versioned_namespace(typename) +self._val = val +self._pointer = val['_M_ptr'] def children(self): -return SmartPtrIterator(self.pointer) +return SmartPtrIterator(self._pointer) # Return the _Sp_counted_base<>* that holds the refcounts. def _get_refcounts(self): -if self.typename == 'std::atomic': +if self._typename == 'std::atomic': # A tagged pointer is stored as uintptr_t. -ptr_val = self.val['_M_refcount']['_M_val']['_M_i'] +ptr_val = self._val['_M_refcount']['_M_val']['_M_i'] ptr_val = ptr_val - (ptr_val % 2) # clear lock bit -ptr_type = find_type(self.val['_M_refcount'].type, 'pointer') +ptr_type = find_type(self._val['_M_refcount'].type, 'pointer') return ptr_val.cast(ptr_type) -return self.val['_M_refcount']['_M_pi'] +return self._val['_M_refcount']['_M_pi'] def to_string(self): state = 'empty' refcounts = self._get_refcounts() -targ = self.val.type.template_argument(0) +targ = self._val.type.template_argument(0) targ = strip_versioned_namespace(str(targ)) if refcounts != 0: @@ -288,7 +294,7 @@ class SharedPointerPrinter: else: state = 'use count %d, weak count %d' % ( usecount, weakcount - 1) -return '%s<%s> (%s)' % (self.typename, targ, state) +return '%s<%s> (%s)' % (self._typename, targ, state) def _tuple_impl_get(val): @@ -347,17 +353,17 @@ def unique_ptr_get(val): return tuple_get(0, tuple_member) -class UniquePointerPrinter: +class UniquePointerPrinter(printer_base): "Print a unique_ptr" def __init__(self, typename, val): -self.val = val +self._val = val def children(self): -return SmartPtrIterator(unique_ptr_get(self.val)) +return SmartPtrIterator(unique_ptr_get(self._val)) def to_string(self): -return ('std::unique_ptr<%s>' % (str(self.val.type.template_argument(0 +return ('std::unique_ptr<%s>' % (str(self._val.type.template_argument(0 def get_value_from_aligned_membuf(buf, valtype): @@ -381,55 +387,56 @@ def get_value_from_list_node(node): raise ValueError("Unsupported implementation for %s" % str(node.type)) -class StdListPrinter: +class StdListPrinter(printer_base): "Print a std::list" class _iterator(Iterator): def __init__(self, nodetype, head): -self.nodetype = nodetype -self.base = head['_M_next'] -self.head = head.address -self.count = 0 +self._nodetype = nodetype +self._base = head['_M_next'] +self