Bug 11777

Summary: Strange behaviour of gdb.Type.fields
Product: gdb Reporter: Andre' <andre.poenitz>
Component: pythonAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: gdb-prs, tromey
Priority: P2    
Version: 7.1   
Target Milestone: 7.1   
Host: i486-linux-gnu Target: i486-linux-gnu
Build: i486-linux-gnu Last reconfirmed:

Description Andre' 2010-07-01 07:20:12 UTC
I sometimes cannot get a proper list of members from structures that do have
members:


This accesses a "real" QRegionPrivate object in a 'QRegion region;':

  python print
gdb.parse_and_eval(\"region\")[\"d\"].dereference()[\"qt_rgn\"].dereference().type

  -> struct myns::QRegionPrivate
 
  python print
gdb.parse_and_eval(\"region\")[\"d\"].dereference()[\"qt_rgn\"].dereference().type.fields()

-> []


If I "create" the type manually I get:
 
  python print gdb.parse_and_eval(\"('myns::QRegionPrivate'*)0\").dereference().type
    -> myns::QRegionPrivate

  python print gdb.parse_and_eval(\"('myns::QRegionPrivate'*)0
\").dereference().type.fields()

    -> [<gdb.Field object at 0xb7764ac0>, <gdb.Field object at 0xb7764af0>,
<gdb.Field object at 0xb7764b20>, <gdb.Field object at 0xb7764b50>, <gdb.Field
object at 0xb7764b80>]

 
Note the extra "struct " in the 'type' output in the first case.

The problem also disappears when I use  type = gdb.lookup_type(str(type)) 
before accessing fields().
Comment 1 Andre' 2010-07-01 07:35:18 UTC
To reproduce:

mkdir x && cd x
echo -e "#include <QRegion>\nint main() { QRegion r; }" > 1.cpp
qmake -project && qmake && make
gdb -ex "b main" -ex "run" -ex "python import gdb" -ex 'python print
gdb.parse_and_eval("r")["d"].dereference()["qt_rgn"].dereference().type.fields()' -ex
'python print
gdb.lookup_type(str(gdb.parse_and_eval("r")["d"].dereference()["qt_rgn"].dereference().type)).fields()'
./x
Comment 2 Andre' 2010-07-01 09:13:06 UTC
To reproduce without Qt:


------------------------- snip ------------------------
mkdir x && cd x


echo -e "struct P { P(); int a, b, c, d; }; " > p.h
echo -e "#include \"p.h\"\n P::P() {} " > p.cpp
echo -e "class P; struct X { X(); P *p; };" > x.h
echo -e " #include \"x.h\"\n X::X() {} " > x.cpp
echo -e "#include \"x.h\"\n int main() { X x; }" > main.cpp

g++ -g -shared -o libxp.so x.cpp p.cpp
g++ -g -o x -L. -lxp main.cpp -Wl,-rpath,`pwd`

gdb -ex "b main" -ex "run" -ex "python import gdb" \
    -ex 'set confirm off' \
    -ex 'python print gdb.parse_and_eval("x")["p"].dereference().type.fields()' \
    -ex 'python print
gdb.lookup_type(str(gdb.parse_and_eval("x")["p"].dereference().type)).fields()' \
    -ex q \
    ./x
------------------------- snip ------------------------
Comment 3 Tom Tromey 2010-07-06 19:52:10 UTC
(In reply to comment #2)

>     -ex 'python print gdb.parse_and_eval("x")["p"].dereference().type.fields()' \

I can make this work by adding a call to strip_typedefs:



(gdb) python print gdb.parse_and_eval ('x')['p'].dereference().type.fields()
[]
(gdb) python print gdb.parse_and_eval
('x')['p'].dereference().type.strip_typedefs().fields()
[<gdb.Field object at 0xb7dbc220>, <gdb.Field object at 0xb7dbc250>, <gdb.Field
object at 0xb7dbc280>, <gdb.Field object at 0xb7dbc2b0>]


Arguably the Python API should be doing this for you.
It seems useless to get the fields of a stub type.
Comment 4 Tom Tromey 2010-08-20 18:27:22 UTC

*** This bug has been marked as a duplicate of 10953 ***