Re: GDB returns wrong type when traversing optimized-out Fields
Roman Popov <[email protected]>
| Newsgroups | gmane.comp.gdb.devel |
|---|---|
| Message-ID | <CAATAM3HEXrZ73EyAXM_+wNREH-nEM+kg4q4_Qo9iZwhugDUGbA@mail.gmail.com> |
Thanks Simon, Your patch solves the issue for all of my clients! -Roman 2018-02-04 21:39 GMT-08:00 Simon Marchi <[email protected]>: > On 2018-02-04 11:06 PM, Roman Popov wrote: > > I apologize for code typo in previous email. Here is correct code sample: > > > > template <unsigned v1, unsigned v2> > > struct TRAITS { > > static const unsigned val1 = v1; > > static const unsigned val2 = v2; > > }; > > template < class TRAITS > > > struct foo { > > static const unsigned x1 = TRAITS::val1; > > static const unsigned x2 = TRAITS::val2; > > }; > > > > int main () { > > foo<TRAITS<1,2>> f1; > > // SET BREAKPOINT HERE > > return 0; > > } > > > > -Roman > > > > > > 2018-02-04 20:02 GMT-08:00 Roman Popov <[email protected]>: > > > >> Hi all, > >> I've encountered strange GDB behavior when requesting a value of > >> optimized-away field. > >> Instead of returning None or raising exception, GDB returns an > >> optimizied-out value of wrong type. > >> > >> Here is a small reproducer *optimize_out.cpp*: > >> > >> template <unsigned v1, unsigned v2> > >> struct TRAITS { > >> static const unsigned val1 = v1; > >> static const unsigned val2 = v2; > >> }; > >> template < class TRAITS > > >> struct foo { > >> static const unsigned x1 = TRAITS::v1; > >> static const unsigned x2 = TRAITS::v2; > >> }; > >> > >> int main () { > >> foo<TRAITS<1,2>> f1; > >> // SET BREAKPOINT HERE > >> return 0; > >> } > >> > >> # Using g++ 7.3 > >> $ g++ -g optimize_out.cpp > >> > >> # Using gdb 8.1 > >> $ gdb a.out > >> > >> (gdb) break optimize_out.cpp:14 > >> (gdb) r > >> (gdb) p f1 > >> $1 = {static x1 = <optimized out>, static x2 = <optimized out>} > >> > >> Ok, looks good. Now traverse fields: > >> > >> (gdb) python > >>> f1 = gdb.parse_and_eval("f1") > >>> for field in f1.type.fields(): > >>> print ("field name: ", field.name, "field type: ", field.type) > >>> field_val = f1[field] > >>> print ("optout?: ",field_val.is_optimized_out, "type: > >> ",field_val.type) > >>> end > >> field name: x1 field type: const unsigned int > >> optout?: True type: foo<TRAITS<1, 2> > > >> field name: x2 field type: const unsigned int > >> optout?: True type: foo<TRAITS<1, 2> > > >> > >> > >> > >> So type we get is foo<TRAITS<1, 2> >, not unsigned int. > >> > >> Looks like GDB-MI has same behavior. At least this code sample totatlly > >> confuses GDB GUI I use. > >> > >> Thanks, > >> Roman > >> > > Hi Roman, > > It just seems to be that we return a value with the type of the structure > instead of the type of the field in an error path somewhere. It causes > these weird behaviors in the CLI too: > > (gdb) p f1 > $1 = {static x1 = <optimized out>, static x2 = <optimized out>} > (gdb) p f1.x1 > $2 = <optimized out> > (gdb) ptype f1.x1 > type = struct foo<TRAITS<1, 2> > [with TRAITS = TRAITS<1, 2>] { > static const unsigned int x1; > static const unsigned int x2; > } > (gdb) ptype f1.x1.x1 > type = struct foo<TRAITS<1, 2> > [with TRAITS = TRAITS<1, 2>] { > static const unsigned int x1; > static const unsigned int x2; > } > (gdb) p f1.x1.x1.x1.x1 > $3 = <optimized out> > > Can you try the patch below? I did not run the testsuite on it. > > > From ef7f73557e291ed2d8bc7f175765bdbb91e2c817 Mon Sep 17 00:00:00 2001 > From: Simon Marchi <[email protected]> > Date: Mon, 5 Feb 2018 00:34:08 -0500 > Subject: [PATCH] Return right type in value_static_field > > --- > gdb/value.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/gdb/value.c b/gdb/value.c > index 9a144fb7fb..063f57129a 100644 > --- a/gdb/value.c > +++ b/gdb/value.c > @@ -2978,7 +2978,10 @@ value_static_field (struct type *type, int fieldno) > = lookup_minimal_symbol (phys_name, NULL, NULL); > > if (!msym.minsym) > - return allocate_optimized_out_value (type); > + { > + struct type *field_type = TYPE_FIELD_TYPE (type, fieldno); > + return allocate_optimized_out_value (field_type); > + } > else > { > retval = value_at_lazy (TYPE_FIELD_TYPE (type, fieldno), > -- > 2.16.1 > > >