https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84847

--- Comment #1 from rguenther at suse dot de <rguenther at suse dot de> ---
On Tue, 13 Mar 2018, dmalcolm at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84847
> 
>             Bug ID: 84847
>            Summary: [8 Regression] Incompatibility between early LTO debug
>                     and "-Wl,--gc-sections" leads to corrupt DWARF
>                     debuginfo
>            Product: gcc
>            Version: 8.0
>             Status: UNCONFIRMED
>           Severity: normal
>           Priority: P3
>          Component: lto
>           Assignee: unassigned at gcc dot gnu.org
>           Reporter: dmalcolm at gcc dot gnu.org
>                 CC: marxin at gcc dot gnu.org, nickc at gcc dot gnu.org,
>                     rguenth at gcc dot gnu.org
>   Target Milestone: ---
> 
> The downstream bug report:
>   https://bugzilla.redhat.com/show_bug.cgi?id=1543912
> describes a problem building systemd and systemd-bootchart with gcc 8, which
> turned out to be due to those packages' configure scripts injecting both
>   -flto
> and
>   -Wl,--gc-sections
> 
> They build fine with just one of them, but with both, the binaries have 
> corrupt
> DWARF debuginfo.
> 
> Adding "-Wl,--print-gc-sections" shows the issue more clearly.
> 
> I created a minimal reproducer here:
>   https://github.com/davidmalcolm/rhbz-1543912
> with which I can reproduce the issue, using:
>   gcc-8.0.1-0.16.fc29.x86_64
>   binutils-2.30-6.fc29.x86_64
> (this is on Fedora in a chroot via "mock -r fedora-rawhide-x86_64 shell"; I'm
> still working on reproducing this outside a chroot)
> 
> $ make
> gcc -I ./src -flto -O2 -g -c src/bootchart.c -o build/bootchart.o
> gcc -I ./src -flto -O2 -g -c src/log.c -o build/log.o
> gcc -flto -g -Wl,--gc-sections -Wl,--print-gc-sections \
>   build/bootchart.o build/log.o \
>           -o build/systemd-bootchart
> /usr/bin/ld: Removing unused section '.rodata.cst4' in file
> '/usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/crt1.o'
> /usr/bin/ld: Removing unused section '.data' in file
> '/usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/crt1.o'
> /usr/bin/ld: Removing unused section '.rodata' in file
> '/usr/lib/gcc/x86_64-redhat-linux/8/crtbegin.o'
> /usr/bin/ld: Removing unused section '.debug_abbrev' in file
> '/tmp/cc1vnNPxdebugobj'
> /usr/bin/ld: Removing unused section '.debug_str' in file
> '/tmp/cc1vnNPxdebugobj'
> /usr/lib/rpm/debugedit build/systemd-bootchart
> /usr/lib/rpm/debugedit: build/systemd-bootchart: Invalid .line_table offset
> 0x2b0803
> /usr/lib/rpm/debugedit: build/systemd-bootchart: Could not find DWARF
> abbreviation 7
> 
> In the above, note how ld has garbage-collected the '.debug_abbrev' and
> '.debug_str' sections from the /tmp/cc*debugobj file.
> 
> Examining the binary via
>   eu-readelf -w build/systemd-bootchart
> shows bogus-looking compile_unit DIEs in the binary:
> 
> DWARF section [23] '.debug_info' at offset 0x10a6:
>  [Offset]
>  Compilation unit at offset 0:
>  Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
>  [     b]  compile_unit
>            producer             (strp) "/builddir/build/BUILD/minimizing-2"
>            language             (data1) C99 (12)
>            name                 (strp) "/builddir/build/BUILD/minimizing-2"
>            comp_dir             (strp) "/builddir/build/BUILD/minimizing-2"
>            ranges               (sec_offset) range list [     2]
>            low_pc               (addr) 0x000000250e030100
>  Compilation unit at offset 105:
>  Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
>  [    74]  compile_unit
>            producer             (strp) "/builddir/build/BUILD/minimizing-2"
>            language             (data1) C99 (12)
>            name                 (strp) "/builddir/build/BUILD/minimizing-2"
>            comp_dir             (strp) "/builddir/build/BUILD/minimizing-2"
>            ranges               (sec_offset) range list [     2]
>            low_pc               (addr) 0x0000870006030100
> 
> Note how every string is using string 0.
> 
> Removing the -Wl,--gc-sections leads to sane-looking DIEs.
> 
> The issue seems to be that lto-wrapper generates /tmp/cc*debugobj files
> containing "early LTO debug info", but, quoting Nick in:
>   https://bugzilla.redhat.com/show_bug.cgi?id=1543912#c22
> >   I have now found out what it happening, although I am still a little bit
> >   confused as to why it should be occurring.  The LTO pass is producing an
> >   object file that only contains debug information:
> >
> >     /dev/shm/ccqhNEybdebugobj
> >
> >   (There was a clue in the filename, but I did not pay attention to this).
> >
> >   The linker's garbage collection code reasons that any file that does not
> >   have *any* allocatable sections[1] can automatically be discarded, since 
> > it
> >   cannot have any effect on the execution of the resulting binary, right ?
> > ...
> >
> >   So this is why the .debug_abbrev and .debug_str sections are being
> > discarded.
> >   I do not know why the LTO pass is producing this file.  Perhaps someone
> > else
> >   more familiar with LTO can explain.
> > 
> >   A simple fix would be remove the code from the linker's garbage collector
> >   that discards non-allocatable input files, but this seems rather heavy 
> >   handed.  I would rather know if there is some way to deduce that a given
> >   file really is needed, despite it only containing debug information, and
> >   then choose to keep it.  I guess it all comes down to why the LTO pass is
> >   generating this file, and what it contains.
> > 
> > Cheers
> >   Nick
> > 
> > [1].  Actually the linker first checks to see if any allocatable sections
> >   can be discarded.  Then if the file did not contain any allocatable
> >   sections, or all of the allocatable sections can be discarded, then the
> >   whole file is discarded.
> 
> Nick has posted a patch for lto-wrapper at:
>   https://bugzilla.redhat.com/show_bug.cgi?id=1543912#c28
> as a workaround for this (actually, a 2nd iteration, based on some nit-picking
> by me - but Richard is the expert at this).

Isn't this the same as
https://sourceware.org/bugzilla/show_bug.cgi?id=20882
which was appearantly set to fixed?

See libstdc++-v3/testsuite/libstdc++-prettyprinters/prettyprinters.exp
which has

if { [check_effective_target_lto] } {
  append cxxflags " -flto"
  # work around sourceware.org 20882
  regsub {^(.*)-Wl,--gc-sections(.*)$} $cxxldflags {\1\2} cxxldflags
  gdb-dg-runtest [lsort [glob $srcdir/$subdir/*.cc]] \
    "" "$DEFAULT_CXXFLAGS -flto $PCH_CXXFLAGS"
}

where I didn't yet verify if the "fixed" binutils works without pruning
--gc-sections.

Reply via email to