On Wed, 26 Feb 2020 at 14:32, Paul Smith <p...@mad-scientist.net> wrote: > > Hi all. I was seeing a strange error in GDB (8.2.1) debugging some C++ > code while trying to print a value. The pretty printer was throwing Python > exceptions. > > Debugging it I discovered the problem, which is here (from GCC 9.2): > > libstdc++-v3/python/libstdcxx/v6/printers.py: > # 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. > def find_type(orig, name): > typ = orig.strip_typedefs() > while True: > # Strip cv-qualifiers. PR 67440. > --> search = '%s::%s' % (typ.unqualified(), name) > try: > return gdb.lookup_type(search) > except RuntimeError: > pass > # The type was not found, so try the superclass. We only need > # to check the first superclass, so we don't bother with > # anything fancier here. > field = typ.fields()[0] > > (First that GDB bug was fixed in 2012 so I'm not sure if we still need this > method, but anyway...) > > The issue is on the marked line above. Here we are using the __str__() > method on a gdb.Type to obtain the string name of the type. However, I've > discovered that (at least on my system) the __str__() representation of a > gdb.Type prepends the keyword "class " or "struct " (as appropriate) to the > output. So the above will result in a string like: > > search = 'class std::unordered_map...::...'
I don't think I've seen that problem before. Are you sure that's the cause, and not something like https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91997 ? > The prepended "class " causes the code to break: it doesn't find the type, > then we try to use typ.fields()[0] which doesn't work as follows: > > Traceback (most recent call last): > ... > File "/cc/python/libstdcxx/v6/printers.py", line 97, in find_type > field = typ.fields()[0] > IndexError: list index out of range > > I think that it's not correct for the Python macros here to be using the > gdb.Type.__str__() method to obtain the type name for anything other than > displaying to users. They should always be using the gdb.Type.name data > member instead. If I change the marked line above to be: > > search = '%s::%s' % (typ.unqualified().name, name) > > then it all works as expected. > > However, I took a quick look through the code and it _appears_ to me that > this type of thing (using the implied, or explicit, gdb.Type.__str__() to > obtain the type name) is done in a number of places. I'm never clear whether we should be using Type.name or Type.tag or Type.__str__() because they all seem to do the wrong thing in different situations. > This makes me wonder whether (a) for some reason no one noticed this > before, or (b) there's something bizarre about my GDB which is prepending > this "class" or "struct" where other peoples' don't do that?