RFC: Make iterator printers fail more gracefully

Jonathan Wakely jwakely@redhat.com
Thu Dec 15 17:39:00 GMT 2016


This patch tries to improve the user experience when debugging
container iterators, for cases where some of the typedefs used by the
printers are not in the debuginfo, so gdb.lookup_type() calls fail.
That happens if the iterator's operator*() and operator->() haven't
been instantiated, or if they've been inlined.

Currently this results in an exception:

$1 = Python Exception <class 'ValueError'> Cannot find type std::_List_iterator<int>::_Node: 

If the iterator being printed is part of some other object the whole
thing fails due to the exception.

With this patch the iterator instead prints:

$1 = <insufficient debuginfo for std::list iterator>

and if it's a subobject the rest of the object is printed, with that
as the value of the iterator.

	* python/libstdcxx/v6/printers.py (StdListIteratorPrinter.to_string):
	Handle exception from failed type lookup and return user-friendly
	string.
	(StdRbtreeIteratorPrinter.__init__): Handle exception from failed
	type lookup.
	(StdRbtreeIteratorPrinter.to_string): Return user-friendly string.

Seem reasonable?

I consider this a stop-gap until we have Xmethods for all our iterator
types, then we'll be able to "print *iter" even without debuginfo for
all the iterator's members, and we can disable these printers.

-------------- next part --------------
commit 1794ede023b36df4eb2c7264e2d04d6a86ad456a
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Dec 15 16:52:21 2016 +0000

    Make iterator printers fail more gracefully
    
    	* python/libstdcxx/v6/printers.py (StdListIteratorPrinter.to_string):
    	Handle exception from failed type lookup and return user-friendly
    	string.
    	(StdRbtreeIteratorPrinter.__init__): Handle exception from failed
    	type lookup.
    	(StdRbtreeIteratorPrinter.to_string): Return user-friendly string.

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 86de1ca..60afb52 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -202,10 +202,13 @@ class StdListIteratorPrinter:
     def to_string(self):
         if not self.val['_M_node']:
             return 'non-dereferenceable iterator for std::list'
-        nodetype = find_type(self.val.type, '_Node')
-        nodetype = nodetype.strip_typedefs().pointer()
-        node = self.val['_M_node'].cast(nodetype).dereference()
-        return str(get_value_from_list_node(node))
+        try:
+            nodetype = find_type(self.val.type, '_Node')
+            nodetype = nodetype.strip_typedefs().pointer()
+            node = self.val['_M_node'].cast(nodetype).dereference()
+            return str(get_value_from_list_node(node))
+        except:
+            return '<insufficient debuginfo for std::list iterator>'
 
 class StdSlistPrinter:
     "Print a __gnu_cxx::slist"
@@ -496,12 +499,17 @@ class StdRbtreeIteratorPrinter:
     def __init__ (self, typename, val):
         self.val = val
         valtype = self.val.type.template_argument(0).strip_typedefs()
-        nodetype = gdb.lookup_type('std::_Rb_tree_node<' + str(valtype) + '>')
-        self.link_type = nodetype.strip_typedefs().pointer()
+        try:
+            nodetype = gdb.lookup_type('std::_Rb_tree_node<' + str(valtype) + '>')
+            self.link_type = nodetype.strip_typedefs().pointer()
+        except:
+            self.link_type = None
 
     def to_string (self):
         if not self.val['_M_node']:
             return 'non-dereferenceable iterator for associative container'
+        if self.link_type is None:
+            return "<insufficient debuginfo for associative container iterator>"
         node = self.val['_M_node'].cast(self.link_type).dereference()
         return str(get_value_from_Rb_tree_node(node))
 


More information about the Libstdc++ mailing list