https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94469
Bug ID: 94469
Summary: lto abstract variable emitted as concrete decl (ada
test-case)
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: debug
Assignee: unassigned at gcc dot gnu.org
Reporter: vries at gcc dot gnu.org
Target Milestone: ---
Consider gdb testsuite test-case gdb.ada/call_pn (
https://sourceware.org/git/?p=binutils-gdb.git;a=tree;f=gdb/testsuite/gdb.ada/call_pn;hb=HEAD
), consisting of files foo.adb, pck.adb and pck.ads.
Compiled like so:
...
$ gnatmake-10 \
--GCC=/usr/bin/gcc-10 \
--GNATBIND=/usr/bin/gnatbind-10 \
--GNATLINK=/usr/bin/gnatlink-10 \
-largs --GCC=/usr/bin/gcc-10 -margs \
src/gdb/testsuite/gdb.ada/call_pn/foo.adb \
-g -flto -O0 -flto-partition=none -ffat-lto-objects
...
When trying to print the value of last_node_id, we get a question which symbol
to print:
...
$ gdb foo -ex "p last_node_id"
Reading symbols from foo...
Multiple matches for last_node_id
[0] cancel
[1] pck.last_node_id at src/gdb/testsuite/gdb.ada/call_pn/pck.adb:17
[2] pck.last_node_id at src/gdb/testsuite/gdb.ada/call_pn/foo.adb:17
>
...
where 1 gives us:
...
> 1
$1 = <optimized out>
...
and 2 gives us:
...
> 2
$1 = 0
...
If we compile without lto, so just with -g, we have instead:
...
$ gdb foo -ex "p last_node_id"
$1 = 0
...
The structure of the dwarf for the lto case is:
...
<0><15ef>: Abbrev Number: 1 (DW_TAG_compile_unit)
<15f5> DW_AT_name : <artificial>
<1><1611>: Abbrev Number: 2 (DW_TAG_imported_unit)
<1612> DW_AT_import : <0x167a> [Abbrev Number: 1]
<1><163f>: Abbrev Number: 5 (DW_TAG_variable)
<1640> DW_AT_abstract_origin: <0x16d4>
<1644> DW_AT_location : 9 byte block: 3 d4 33 63 0 0 0 0 0
(DW_OP_addr: 6333d4)
<0><167a>: Abbrev Number: 1 (DW_TAG_compile_unit)
<1680> DW_AT_name : src/gdb/testsuite/gdb.ada/call_pn/pck.adb
<1><16d4>: Abbrev Number: 8 (DW_TAG_variable)
<16d5> DW_AT_name : pck__last_node_id
...
My understanding of DWARF is that this actually declares three symbols:
- the one for DW_TAG_compile_unit pck.adb
- the one for DW_TAG_compile_unit <artificial>
- the one resulting from the import of <pck.adb> into DW_TAG_compile_unit
<artificial>
And, AFAIU, the way to make sure we declare just one symbol is by both:
- dropping the import, and
- changing the tag for pck.adb to DW_TAG_partial_unit.
The import was already dropped on master by commit 54af95767e8 "debug/94450 -
remove DW_TAG_imported_unit generated in LTRANS units" ( see PR 94450 comment 6
).
Note: interestingly, the foo.adb here is incorrect:
...
[1] pck.last_node_id at src/gdb/testsuite/gdb.ada/call_pn/pck.adb:17
[2] pck.last_node_id at src/gdb/testsuite/gdb.ada/call_pn/foo.adb:17
...
For now I'm assuming that's a gdb PR, filed as
PR gdb/25771 - "Inter-cu DW_AT_abstract_origin results in wrong file".