Bug 10953 - gdb.Type does not give access to Base classes
Summary: gdb.Type does not give access to Base classes
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: python (show other bugs)
Version: 7.0
: P2 normal
Target Milestone: 7.3
Assignee: Tom Tromey
URL:
Keywords:
: 11777 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-11-13 15:55 UTC by Andre'
Modified: 2010-08-23 20:31 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Last reconfirmed: 2010-08-20 18:34:45


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andre' 2009-11-13 15:55:36 UTC
That's archer-tromey-python, at dad6b53fe4

The problem is that gdb.selected_frame().read_var("d").type.fields()  reports an
empty list. The list becomes non-empty as soon as the contents of derived.cpp is
moved to main.cpp.

------------------ Makefile ------------------
run:
        g++ -g base.cpp derived.cpp main.cpp -o yy
        ~/bin/gdb-archer -ex 'b main' -ex 'run' \
          -ex 'python print gdb.selected_frame().read_var("d").type.fields()' \
          ./yy


------------------ base.h ------------------
#ifndef BASE_H
struct Base
{
    virtual ~Base();
};
#endif


------------------ base.cpp ------------------
#include "base.h"

Base::~Base() {}


------------------ derived.h ------------------
#ifndef DERIVED_H

#include "base.h"

struct Derived : Base
{
    virtual ~Derived();
};
#endif


------------------ derived.cpp ------------------
#include "derived.h"

Derived::~Derived() {}


------------------ main.cpp ------------------

#include "derived.h"

int main()
{
    Derived d;
}
~
Comment 1 Phil Muldoon 2009-11-17 17:03:15 UTC
If you add a call to strip_typedef() it will work:

python print
gdb.selected_frame().read_var("d").type.strip_typedefs().fields()[0].name
Base

I asked Dodji to help with this bug, and he should be updating the "why" this is
necessary in a far more eloquent way than I could ;)
Comment 2 Dodji Seketeli 2009-11-18 08:08:36 UTC
The short story is that the "Derived" type is considered "not complete" by GCC -
in the compilation unit main.cpp - so, no debug info is emitted for its
*definition*, in that compilation unit. The DIE describing "Derived" then has a
DW_AT_declaration set. So GDB has to go lookup the DIE of the *definitin* of
"Derived" in another compilation unit.

Now I guess the outstanding question is "why is Derived considered not complete?".
GCC implements a scheme to reduce debug info size. In that scheme, when a type
has as virtual table (like Derived, because it has a virtual destructor
declared), GCC only emits full debug info for said type _only_ if the virtual
table is emitted. In this case, as the virtual destructor of Derived is not
*defined* in main.cpp, no virtual table is emitted in that compilation unit. I
guess the virtual table for Derived will be emitted in another compilation unit
where the virtual destructor would be emitted.

To wrap things up in another way, no virtual destructor defined in current CU =>
no vtable emitted for Derived in current CU => no full debug info for Derived in
current CU => GDB has to fetch the full debug info for Derived in another CU.
Comment 3 Phil Muldoon 2009-11-24 17:27:21 UTC
More a GCC quirk than anything else.
Comment 4 Andre' 2010-05-26 13:54:12 UTC
Would there be a way to detect this situation within gdb and possibly do
"something" to gain access to the "missing" information?

If so, maybe the "type" access in Python could trigger this automatically?
Comment 5 Andre' 2010-05-26 14:24:37 UTC
This will get more even more "interesting" when gcc 4.5 hits the masses as a
'print b' in

void Derived::foo()
{
    Base *b = this;
    Base &br = *b;
}

yields  "$1 = (void *) 0xbfffee38", i.e. the type information for 'b' is
completely lost.

Comment 6 Andre' 2010-05-26 15:07:15 UTC
The second example seems to be unrelated, I opened
http://sourceware.org/bugzilla/show_bug.cgi?id=11639 for it.
Comment 7 Tom Tromey 2010-08-11 20:54:47 UTC
I don't think this is invalid.

Instead I tend to think that the "fields" method should call check_typedef first.
This seems a lot more useful than the current behavior.
If there is a case where someone really needs to know that a type is incomplete,
we can add an attribute indicating that.
Comment 8 Tom Tromey 2010-08-20 18:27:22 UTC
*** Bug 11777 has been marked as a duplicate of this bug. ***
Comment 9 Tom Tromey 2010-08-20 18:34:45 UTC
Testing a patch.
Comment 10 Sourceware Commits 2010-08-23 20:24:09 UTC
Subject: Bug 10953

CVSROOT:	/cvs/src
Module name:	src
Changes by:	tromey@sourceware.org	2010-08-23 20:23:55

Modified files:
	gdb            : ChangeLog 
	gdb/python     : py-type.c 

Log message:
	PR python/10953:
	* python/py-type.c (typy_fields): Call check_typedef.
	(typy_template_argument): Add TRY_CATCH.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.12106&r2=1.12107
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/python/py-type.c.diff?cvsroot=src&r1=1.12&r2=1.13

Comment 11 Tom Tromey 2010-08-23 20:31:21 UTC
I checked in the fix.