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
>
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.