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.

Reply via email to