Discussion:
[Bug gdb/20426] New: gdb does not interpret DWARF annotating imported units fully
rguenth at gcc dot gnu.org
2016-08-01 12:25:53 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=20426

Bug ID: 20426
Summary: gdb does not interpret DWARF annotating imported units
fully
Product: gdb
Version: 7.11.1
Status: NEW
Severity: normal
Priority: P2
Component: gdb
Assignee: unassigned at sourceware dot org
Reporter: rguenth at gcc dot gnu.org
Target Milestone: ---

Created attachment 9412
--> https://sourceware.org/bugzilla/attachment.cgi?id=9412&action=edit
partially linked executable

For

int main(int argc, char **argv)
{
void *a[argc-1];
for (int i = 1; i < argc; ++i)
a[i-1] = argv[i];
return 0;
}

when compiled with GCC LTO in a private branch produces the attached
debug info. gdb is not able to pick up DW_AT_upper_bound for the VLA
type correctly. GCC emits it like

<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_producer : (indirect string, offset: 0x44): GNU C11 7.0.0
201
60801 (experimental) [trunk revision 221942] -mtune=generic -march=x86-64 -g
-fl
to
<10> DW_AT_language : 12 (ANSI C99)
<11> DW_AT_name : t.c
<15> DW_AT_comp_dir : (indirect string, offset: 0xa):
/abuild/rguenther
/obj-early-lto-debug-g/gcc
<1><19>: Abbrev Number: 2 (DW_TAG_subprogram)
<1a> DW_AT_external : 1
<1a> DW_AT_name : (indirect string, offset: 0x3f): main
...
<2><3e>: Abbrev Number: 4 (DW_TAG_variable)
<3f> DW_AT_type : <0x72>
<43> DW_AT_artificial : 1
...
<2><43>: Abbrev Number: 5 (DW_TAG_variable)
<44> DW_AT_name : a
<46> DW_AT_decl_file : 1
<47> DW_AT_decl_line : 3
<48> DW_AT_type : <0x79>
...
<1><79>: Abbrev Number: 10 (DW_TAG_array_type)
<7a> DW_AT_type : <0x8c>
<7e> DW_AT_sibling : <0x8c>
<2><82>: Abbrev Number: 11 (DW_TAG_subrange_type)
<83> DW_AT_type : <0x72>
<87> DW_AT_upper_bound : <0x3e>
<2><8b>: Abbrev Number: 0
...
<0><9a>: Abbrev Number: 1 (DW_TAG_compile_unit)
<9b> DW_AT_producer :
<9c> DW_AT_language : 12 (ANSI C99)
<9d> DW_AT_low_pc : 0x0
<a5> DW_AT_high_pc : 0xfd
<ad> DW_AT_stmt_list : 0x0
<1><b1>: Abbrev Number: 2 (DW_TAG_imported_unit)
<b2> DW_AT_import : <0xb> [Abbrev Number: 1]
<1><b6>: Abbrev Number: 3 (DW_TAG_subprogram)
<b7> DW_AT_abstract_origin: <0x19>
<bb> DW_AT_low_pc : 0x0
<c3> DW_AT_high_pc : 0xfd
<cb> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<cd> DW_AT_GNU_all_call_sites: 1
...
<2><df>: Abbrev Number: 5 (DW_TAG_variable)
<e0> DW_AT_abstract_origin: <0x3e>
<e4> DW_AT_location : 2 byte block: 91 60 (DW_OP_fbreg: -32)
<2><e7>: Abbrev Number: 5 (DW_TAG_variable)
<e8> DW_AT_abstract_origin: <0x43>
<ec> DW_AT_location : 4 byte block: 91 a0 7f 6 (DW_OP_fbreg:
-96; DW_OP_deref)
...

where nothing in the DWARF standard suggests that the above wouldn't complete
DW_AT_upper_bound properly (it doesn't matter whether abstract origin or
specification is used). It would be a shame if the importing CU needs
to pull in the array type its subrange type just to adjust its upper bound.

Note that it doesn't seem to matter (for gdb) whether the importing CU
refers to the imported DIEs via DW_AT_abstract_origin or DW_AT_specification.
--
You are receiving this mail because:
You are on the CC list for the bug.
mjw at redhat dot com
2016-08-26 23:36:12 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=20426

Mark Wielaard <mjw at redhat dot com> changed:

What |Removed |Added
----------------------------------------------------------------------------
CC| |mjw at redhat dot com
--
You are receiving this mail because:
You are on the CC list for the bug.
mjw at redhat dot com
2016-08-29 11:06:54 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=20426

--- Comment #1 from Mark Wielaard <mjw at redhat dot com> ---
I admit to not know anything about how gdb implements this. But looking at the
DIE tree I think it is not surprising the location of the upper_bound cannot be
found.

In other DWARF consumers I have worked with following the specification or
abstract origin attribute is used to augment the current DIE under
consideration, not the other way around. To make it work the other way around a
DWARF consumer would have to keep track of all references through
DW_AT_specification or DW_AT_abstract_origin to a specific DIE.

In this case what a DWARF consumer probably would do is find the the subprogram
[b6] based on the address (main function) that it covers. If the user wants to
inspect the variable "a" it will find [e7] (with the name given through the
DW_AT_specification to [43]). Now this variable DIE [e7] will then be passed to
some function to resolve it (find the location expression). Given such a
variable DIE is normally enough to resolve all relevant location information.
In this case it points to the array_type [79] and finally the upper_bound,
which points to the variable described at [3e]. Following the DIE reference
chain there is nothing indicating that the missing location expression for that
variable can be found through the [df] DIE in the other compilation unit.

It is not immediately clear to me which heuristic needs to be used to deduce
that the [df] DIE specification attribute pointing to [e3] needs to be
remembered as back reference (assuming it has even has been seen yet by DWARF
reader, if the variable and formal_parameter were in a different order in the
tree we might not even have seen it yet). Or how the consumer can be sure it
has seen and collected all such back-references needed (assuming we do want the
DWARF consumer to be as efficient as possible by reading as little of the DIE
tree as possible).
--
You are receiving this mail because:
You are on the CC list for the bug.
mjw at redhat dot com
2016-08-29 11:17:33 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=20426

--- Comment #2 from Mark Wielaard <mjw at redhat dot com> ---
(In reply to Mark Wielaard from comment #1)
Post by mjw at redhat dot com
In other DWARF consumers I have worked with following the specification or
abstract origin attribute is used to augment the current DIE under
consideration, not the other way around. To make it work the other way
around a DWARF consumer would have to keep track of all references through
DW_AT_specification or DW_AT_abstract_origin to a specific DIE.
And I think it is not a 1-on-1 relationship. There could be multiple DIEs
pointing to the same abstract_origin (maybe the function got cloned). So the
consumer might not even know which one to pick.
--
You are receiving this mail because:
You are on the CC list for the bug.
rguenth at gcc dot gnu.org
2016-08-30 08:11:38 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=20426

--- Comment #3 from Richard Guenther <rguenth at gcc dot gnu.org> ---
(In reply to Mark Wielaard from comment #2)
Post by mjw at redhat dot com
(In reply to Mark Wielaard from comment #1)
Post by mjw at redhat dot com
In other DWARF consumers I have worked with following the specification or
abstract origin attribute is used to augment the current DIE under
consideration, not the other way around. To make it work the other way
around a DWARF consumer would have to keep track of all references through
DW_AT_specification or DW_AT_abstract_origin to a specific DIE.
And I think it is not a 1-on-1 relationship. There could be multiple DIEs
pointing to the same abstract_origin (maybe the function got cloned). So the
consumer might not even know which one to pick.
That's true. I guess I can even end up with such a case. I expected the
consumer to pick the annotation in the same context (probably a bit
optimistic).

I can follow your reasoning about how dwarf consumers work.

It's somewhat unfortunate that for my specific use case I have to replicate
all non-abstract parts of a DIE - esp. that I need to adjust the reference
to the type of 'a'. I wonder what DWARF says about duplicate DW_AT_type
(one in the concrete and one "different" in the abstract instance) - do
both DW_AT_type complement each other or does the concrete one "hide" the
abstract one. That is, can I omit DW_AT_type from the DW_TAG_array_type
in the concrete instance and expect it to be picked from the abstract
instance?

Now thinking about how to implement this at all given I have no way to
recreate the type DIEs at the point I can produce the location for
the upper bound...
--
You are receiving this mail because:
You are on the CC list for the bug.
mark at klomp dot org
2017-10-11 10:44:23 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=20426

Mark Wielaard <mark at klomp dot org> changed:

What |Removed |Added
----------------------------------------------------------------------------
CC| |mark at klomp dot org
--
You are receiving this mail because:
You are on the CC list for the bug.
mjw at fedoraproject dot org
2017-10-11 10:49:05 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=20426

Mark Wielaard <mjw at fedoraproject dot org> changed:

What |Removed |Added
----------------------------------------------------------------------------
CC|mjw at fedoraproject dot org |
--
You are receiving this mail because:
You are on the CC list for the bug.
vries at gcc dot gnu.org
2018-09-05 10:58:56 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=20426

Tom de Vries <vries at gcc dot gnu.org> changed:

What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
CC| |vries at gcc dot gnu.org
Resolution|--- |FIXED
Target Milestone|--- |8.3

--- Comment #4 from Tom de Vries <vries at gcc dot gnu.org> ---
With commit "[gdb/exp] Handle DW_OP_GNU_variable_value refs to abstract dies"
( https://sourceware.org/ml/gdb-cvs/2018-09/msg00016.html ), I think this issue
should be resolved.
--
You are receiving this mail because:
You are on the CC list for the bug.
Loading...