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.)

Reply via email to