Types prefixed by "class" or "struct" string??

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Types prefixed by "class" or "struct" string??

Paul Smith-20
Something very odd is going on.  I'm using GCC 8.1 and GDB 8.2.1 with
Python support (GNU/Linux on x86_64), and I've been using them for quite a
while (I've built them myself and put them into a Git repository, along
with binutils 2.33.1 and a sysroot).

I can't say for sure that this is different or has always happened but
certainly I just started noticing it recently and I can't think of anything
that's changed in my environment.

What's happening is that when the GDB Python interface retrieves a type as
a string the name of the type is prefixed by "class " (if it's a class) or
"struct " if it's a struct.  So for example if I try to print a
std::list<Foo> variable, I'm getting these exceptions from GDB:

(gdb) p $o->pending
$28 = empty std::__cxx11::listTraceback (most recent call last):
  File "/cc/python/libstdcxx/v6/printers.py", line 243, in children
    nodetype = find_type(self.val.type, '_Node')
  File "/cc/python/libstdcxx/v6/printers.py", line 99, in find_type
    raise ValueError("Cannot find type %s::%s" % (str(orig), name))
ValueError: Cannot find type class std::__cxx11::list<Object::Pending, std::allocator<Object::Pending> >::_Node

Look carefully at the message and you'll see that the value of
self.val.type is not just the type, but the type prefixed by "class ".

If I try to look up a type without the "class " prefix it works fine:

(gdb) python
>t = gdb.lookup_type('std::__cxx11::list<Object::Pending, std::allocator<Object::Pending> >::_Node')
>print str(t)
>^D
std::__cxx11::list<Object::Pending, std::allocator<Object::Pending> >::_Node

But, if I try to look up the type including the "class " it definitely
fails:

(gdb) python
>t = gdb.lookup_type('class std::__cxx11::list<Object::Pending, std::allocator<Object::Pending> >::_Node')
>^D
Traceback (most recent call last):
  File "<string>", line 1, in <module>
gdb.error: No type named class std::__cxx11::list<Object::Pending, std::allocator<Object::Pending> >::_Node.
Error while executing Python code.

Does anyone know what might be causing this or how to avoid it?

For my own python macros I can strip out the prefix before I look up types,
but obviously I can't do that for the stdcxx printer macros that come with
GCC.  And I don't remember needing to do that before.  I'm very confused...

Reply | Threaded
Open this post in threaded view
|

Re: Types prefixed by "class" or "struct" string??

Paul Koning-6


> On Feb 21, 2020, at 9:48 AM, Paul Smith <[hidden email]> wrote:
>
> ...
> If I try to look up a type without the "class " prefix it works fine:
>
> (gdb) python
>> t = gdb.lookup_type('std::__cxx11::list<Object::Pending, std::allocator<Object::Pending> >::_Node')
>> print str(t)
>> ^D
> std::__cxx11::list<Object::Pending, std::allocator<Object::Pending> >::_Node
>
> But, if I try to look up the type including the "class " it definitely
> fails:

Well, sure.  "class" is not part of the name of the type.  

Also note that class and struct are basically synonyms, the only difference is whether the default access is private (class) or public (struct).  While by tradition "struct" is used when defining "plain old data" that is not a requirement.

        paul


Reply | Threaded
Open this post in threaded view
|

Re: Types prefixed by "class" or "struct" string??

Paul Smith-20
On Fri, 2020-02-21 at 09:55 -0500, Paul Koning wrote:
> > But, if I try to look up the type including the "class " it
> > definitely fails:
>
> Well, sure.  "class" is not part of the name of the type.

Heh.  Well, clearly :).  I think I didn't make something clear in my
initial message: it's not *ME* that's providing the "class " prefix:
GDB is doing that itself.  That's the problem: it's adding this prefix
to the names of types, then when it tries to look them up it fails.

However I've discovered the culprit, although I still can't understand
why I never saw this before / what could have changed.

Basically, if you evaluate a gdb.Type in a string context GDB adds the
"class" or "struct" prefix; I guess that's part of the __str__
representation for the gdb.Type class?

Example:

  (gdb) python
  > o = gdb.convenience_variable('o')
  > print o['pending'].type
  > ^D
  class std::__cxx11::list<Object::Pending, std::allocator<Object::Pending> >

But if I use the .name attribute, then I don't get the prefix:

  (gdb) python
  > o = gdb.convenience_variable('o')
  > print o['pending'].type.name
  > ^D
  std::__cxx11::list<Object::Pending, std::allocator<Object::Pending> >

Unfortunately the Python macros that come with GCC's STL use the string
conversion in the pretty-printer code; for example:

  def find_type(orig, name):
      typ = orig.strip_typedefs()
      while True:
          # Strip cv-qualifiers.  PR 67440.
          search = '%s::%s' % (typ.unqualified(), name)

If this used type.unqualified().name instead it would probably be OK.

But, this kind of thing is done EVERYWHERE in the GCC pretty-printers
so it can't possibly have always been this way or nothing would work!!

I simply don't understand how I could have not run into such a
fundamental issue before: as I said I've been using all these same
versions, built locally and checked into Git, for well over a year now.

Has GDB always provided this "class" / "struct" prefix in the __str__
representation of gdb.Type?