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?

Reply via email to