https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94450
Bug ID: 94450 Summary: lto abstract variable emitted as concrete decl 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 test-case test.c: ... int aaa; int main (void) { return aaa; } ... Compiled with -flto: ... $ gcc-10 -O0 test.c -g -flto -flto-partition=none -ffat-lto-objects ... The debug info for the variable aaa looks like this: ... <0><d2>: Abbrev Number: 1 (DW_TAG_compile_unit) <d8> DW_AT_name : <artificial> <1><f4>: Abbrev Number: 2 (DW_TAG_imported_unit) <f5> DW_AT_import : <0x12b> [Abbrev Number: 1] <1><f9>: Abbrev Number: 3 (DW_TAG_variable) <fa> DW_AT_abstract_origin: <0x13d> <fe> DW_AT_location : 9 byte block: 3 2c 10 60 0 0 0 0 0 (DW_OP_addr: 60102c) <0><12b>: Abbrev Number: 1 (DW_TAG_compile_unit) <131> DW_AT_name : test.c <1><13d>: Abbrev Number: 2 (DW_TAG_variable) <13e> DW_AT_name : aaa <142> DW_AT_decl_file : 1 <143> DW_AT_decl_line : 1 <144> DW_AT_decl_column : 5 <145> DW_AT_type : <0x149> <149> DW_AT_external : 1 ... When printing the symbol tables in gdb: ... $ gdb -readnow -batch a.out -ex "maint print symbols" ... it turns out we have two symbols aaa, one here: ... Symtab for file test.c at 0x23aeeb0 Compilation directory is /home/vries Read from object file /home/vries/a.out (0x238cc90) Language: c Blockvector: block #000, object at 0x23af030, 1 syms/buckets in 0x0..0x0 int aaa; unresolved block #001, object at 0x23aef80 under 0x23af030, 1 syms/buckets in 0x0..0x0 typedef int int; Compunit user: 0x23aedf0 ... and one here: ... Symtab for file <artificial> at 0x23aedf0 Compilation directory is /home/vries Read from object file /home/vries/a.out (0x238cc90) Language: c Blockvector: block #000, object at 0x23aecb0, 1 syms/buckets in 0x400492..0x40049e int aaa; static at 0x60102c section .bss int main(void); block object 0x23aebf0, 0x400492..0x40049e section .text block #001, object at 0x23aec50 under 0x23aecb0, 0 syms/buckets in 0x400492..0x40049e block #002, object at 0x23aebf0 under 0x23aec50, 0 syms/buckets in 0x400492..0x40049e, function main Compunit include: 0x23aeeb0 ... If we do "print aaa" in gdb and gdb finds the 'static' aaa symbol first, it uses the DW_AT_location to find the address of the variable. If we do "print aaa" in gdb and gdb finds the 'unresolved' aaa symbol first, it looks in the minimal symbols for a symbol aaa and uses that address. In both cases, we'd find the same address and print the same value, so there's no correctness problem for this example. But with ada, we run into PR gdb/25760 - "[gcc -flto] FAIL: gdb.ada/call_pn.exp: print last_node_id after calling pn (timeout)", which means that there is a correctness problem. It's an idea to try to ignore these useless decls in gdb (filed as PR gdb/25759 - "Remove useless decls from symtab"), but I'm not sure yet how easy it is to do this efficiently. So, it would be good if gcc could make it explicit in the DWARF that there's only one symbol to be considered, rather than having gdb spent time to ignore the abstract one. ISTM the only way to do this is to make the test.c CU a partial unit (using DW_TAG_partial_unit) and drop the import. [ Having said that, I'm not sure that gdb in its current state would correctly interpret such dwarf and only create one symbol, so that might require an additional gdb fix. ]