https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97026
Bug ID: 97026 Summary: -flto and DW_AT_GNU_macros Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: palves at redhat dot com Target Milestone: --- 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? 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? (Maybe GCC could do without that whole DW_AT_abstract_origin indirection too, no clue.)