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.

commit 1794ede023b36df4eb2c7264e2d04d6a86ad456a
Author: Jonathan Wakely <jwak...@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))
 

Reply via email to