https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97026
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |rguenth at gcc dot gnu.org Ever confirmed|0 |1 Last reconfirmed| |2020-09-14 Status|UNCONFIRMED |NEW Keywords| |lto Version|unknown |10.2.0 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Pedro Alves from comment #0) > With: > > #define ZERO 0 > int main () { return ZERO; } > > Compiled with -flto and -g3 so we emit macro debug info: > > $ gcc macro.c -o macro -flto -g3 > > Using gcc version 11.0.0 20200910, commit 3d0af0c997fe, > we end up with a "DW_AT_name: <artificial>" compile unit that basically > wraps another with DW_AT_abstract_origin: > > ~~~~~~~~~~~~~~~~~~~~~ > Compilation Unit @ offset 0x0: > Length: 0x41 (32-bit) > Version: 4 > Abbrev Offset: 0x0 > Pointer Size: 8 > <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit) > <c> DW_AT_producer : (indirect string, offset: 0x12): GNU GIMPLE > 11.0.0 20200910 (experimental) -mtune=generic -march=x86-64 -g -g3 > -fno-openmp -fno-openacc -fPIC > -fcf-protection=none -fltrans > <10> DW_AT_language : 12 (ANSI C99) > <11> DW_AT_name : (indirect string, offset: 0x5): <artificial> > <15> DW_AT_comp_dir : (indirect string, offset: 0x0): /tmp > <19> DW_AT_low_pc : 0x118e > <21> DW_AT_high_pc : 0xb > <29> DW_AT_stmt_list : 0x0 > <1><2d>: Abbrev Number: 2 (DW_TAG_subprogram) > <2e> DW_AT_abstract_origin: <0x66> > <32> DW_AT_low_pc : 0x118e > <3a> DW_AT_high_pc : 0xb > <42> DW_AT_frame_base : 1 byte block: 9c > (DW_OP_call_frame_cfa) > <44> DW_AT_GNU_all_call_sites: 1 > <1><44>: Abbrev Number: 0 > Compilation Unit @ offset 0x45: > Length: 0x31 (32-bit) > Version: 4 > Abbrev Offset: 0x24 > Pointer Size: 8 > <0><50>: Abbrev Number: 1 (DW_TAG_compile_unit) > <51> DW_AT_producer : (indirect string, offset: 0x282f): GNU C17 > 11.0.0 20200910 (experimental) -mtune=generic -march=x86-64 -g3 -flto > <55> DW_AT_language : 12 (ANSI C99) > <56> DW_AT_name : (indirect string, offset: 0x287d): macro.c > <5a> DW_AT_comp_dir : (indirect string, offset: 0x0): /tmp > <5e> DW_AT_stmt_list : 0x41 > <62> DW_AT_GNU_macros : 0x0 > <1><66>: Abbrev Number: 2 (DW_TAG_subprogram) > <67> DW_AT_external : 1 > <67> DW_AT_name : (indirect string, offset: 0x27c8): main > <6b> DW_AT_decl_file : 1 > <6c> DW_AT_decl_line : 3 > <6d> DW_AT_decl_column : 5 > <6e> DW_AT_type : <0x72> > [...] > ~~~~~~~~~~~~~~~~~~~~~ > > Notice however how DW_AT_GNU_macros appears in the latter "abstract" > compilation unit, but not in the "DW_AT_name: <artificial>" "concrete" > compilation unit. > > When GDB wants to access the macros visible in the current function, it > looks up the compilation unit for the current PC, and that finds the > "<artificial>" compilation unit, since that is the concrete one with the > DW_AT_low_pc / DW_AT_high_pc ranges. But since that compilation unit does > not have the DW_AT_GNU_macros attribute, GDB does not find the macro debug > information at all: > > $ gdb ./macro > ... > (gdb) start > Temporary breakpoint 1 at 0x1192: file macro.c, line 3. > Starting program: /tmp/macro > > Temporary breakpoint 1, main () at macro.c:3 > 3 int main () { return ZERO; } > (gdb) p ZERO > No symbol "ZERO" in current context. > > Looking at the DWARF5 specification, I did not find anything suggesting that > DW_AT_abstract_origin would also cause the abstract origin's compile unit's > properties like DW_AT_GNU_macros to also be "inlined" into the concrete > compile unit. > > So... this seems like a compiler bug to me. How is this officially supposed > to work? How is the debugger supposed to find the macro info for a PC of a > function described by the concrete compilation unit? I have no idea how DWARF intends it to work. So - you're a debugger guy - how would you like the compiler to output things? Note ... > The > "<5e> DW_AT_stmt_list : 0x41" > in the abstract compilation unit also looks suspect. The .debug_line info > at offset 0x41 has no line number statements. > > Something made GCC emit the real line info: > "<29> DW_AT_stmt_list : 0x0" > in the concrete "<artificial>" compilation unit. > Why isn't DW_AT_GNU_macros emitted there instead too? The information to generate the .debug_macro section isn't available at link-time. I did expect the debug consumer to pick up DW_AT_GNU_macros via the abstract origin. I'm quite sure that making the concrete CU have a DW_AT_GNU_macros but pointing to the early generated would confuse consumers since .debug_line doesn't have a DW_AT_comp_dir all its files are relative to, so a .debug_line seems to be tied to a specific CU and thus the same applies to a .debug_macro section. compile and link do not necessarily happen from the same CWD and thus their DW_AT_comp_dir might not agree. Also the link-time CU might combine two different source TUs and thus would have to inherit two different macro sections. At some point GCC generated DW_TAG_imported_unit entries in the concrete CUs, but it was pointed out that this shouldn't be necessary and instead would confuse gdb, making it less efficient. > (Maybe GCC could do without that whole DW_AT_abstract_origin indirection > too, no clue.) ... eliding this isn't possible. We output the abstract CU at compilation time and the concrete CU at link time. The .debug_line in the abstract CU is similar to that of a split-dwarf unit - it is a "stub" just needed for file/directory tables.