[Bug lto/101473] New: LTO makes debug info depend on toolchain path
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101473 Bug ID: 101473 Summary: LTO makes debug info depend on toolchain path Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto Assignee: unassigned at gcc dot gnu.org Reporter: tonyb at cybernetics dot com CC: marxin at gcc dot gnu.org Target Milestone: --- When compiling with -flto -g, the resulting debug info varies depending on the install path of the compiler toolchain. This is a problem for reproducible builds (https://reproducible-builds.org/) when the compiler toolchain is installed in the user home directory. For example, when compiling a file lto_test.c with the same toolchain copied into two different paths, readelf -a shows the following: toolchain path 1: 23: 05f5 0 NOTYPE WEAK HIDDEN28 lto_test.c.79b8ff9a toolchain path 2: 42: 05f5 0 NOTYPE WEAK HIDDEN28 lto_test.c.bba5e59b The -frandom-seed flag does not help in this case. The output is deterministic (same output across multiple runs). With -flto disabled, the problem goes away. Non-LTO binaries are identical regardless of the compiler toolchain path. Stripping the debug info from the LTO binaries makes them identical, but using "objcopy --add-gnu-debuglink" makes them different again because the embedded checksum for the debug info is different. I encountered this problem trying to make reproducible builds with -flto under Yocto. Here is the Yocto bug report, including test code for Yocto: https://bugzilla.yoctoproject.org/show_bug.cgi?id=14481 Regarding the "LTO reproducible build test" attachment in the Yocto bug report: Yocto sets up the compiler toolchain in a "recipe-sysroot-native" directory and the system lib/, include/, and such in a "recipe-sysroot" directory, which are prepared by running "bitbake lto-test". Then the run-lto-test script makes two copies of the compiler toolchain under two differnet names using "cp -rl", compiles the simple test program using both toolchains, and compares them. Comment 6 on this bug may be related: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66305#c6
[Bug lto/101473] LTO makes debug info depend on toolchain path
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101473 --- Comment #3 from tonyb at cybernetics dot com --- The output is reproducible for me with that test program too. Try this program instead: #include #include int main(int argc, char **argv) { if (freopen("/dev/null", "w", stdout) == NULL) return 1; return 0; }
[Bug lto/101473] LTO makes debug info depend on toolchain path
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101473 --- Comment #4 from tonyb at cybernetics dot com --- By "reproducible" I meant that with your test program, the binary output was the same regardless of the toolchain path as in https://reproducible-builds.org/, so the "problem" was not reproduced for me with your test program.
[Bug lto/101473] LTO makes debug info depend on toolchain path
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101473 --- Comment #6 from tonyb at cybernetics dot com --- The only thing I know is that roughly similar issues were handled with the -fdebug-prefix-map=old=new switch, but I am not the expert.
[Bug debug/101473] debug_line info depends on toolchain path
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101473 --- Comment #11 from tonyb at cybernetics dot com --- That change fixed the simple test program. Next I will try a more complex program, but it will take a while for everything to compile.
[Bug debug/101473] debug_line info depends on toolchain path
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101473 --- Comment #12 from tonyb at cybernetics dot com --- The patch fixed my own programs, so I rebuilt all of Yocto with -flto in two different directories. I found that most shared libraries in /lib and /usr/lib still have the problem (i.e. are still not binary reproducible), as well as binaries from pciutils, e2fsprogs, dropbear, sysvinit, hdparm, and a few other packages (they are all binary reproducible without -flto). However, the patch certainly did improve things, since some binaries that were different previously are now the same.
[Bug debug/101473] debug_line info depends on toolchain path
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101473 --- Comment #17 from tonyb at cybernetics dot com --- (In reply to Richard Biener from comment #16) > I'm interested if remaining differences are due to the same underlying issue > or not I tested your updated patch with gcc 10.2 (I had to make a small change due to the definition of struct dwarf_file_data being in dwarf2out.c rather than dwarf2out.h in gcc 10.2). I got the same results as before, with the same list of files being non-reproducible. I decided to debug the problem with pciutils. For pciutils, the problem was caused by the following: Yocto CFLAGS contains -ffile-prefix-map but LDFLAGS doesn't. The pciutils Makefile compiles *.c files to *.o files with CFLAGS and links them with LDFLAGS but not CFLAGS. With LTO disabled, this results in a reproducible binary, but with LTO enabled, this results in a non-reproducible binary. So I can workaround by adding -ffile-prefix-map to LDFLAGS. So is this considered a bug? If the prefix map translation can be handled completely before generating the *.o file, then it could be fixed in gcc, but I am not sure how it all works. One solution that is apparently off the table is embedding the prefix map in the *.o file, since that would make the *.o file non-reproducible (see e.g. bug 68848; apparently the prefix map used to be present in the *.o file but was removed in some recent version of gcc). If this issue is not considered a bug, then I will pass on to the Yocto people that they should use -ffile-prefix-map in LDFLAGS in addition to CFLAGS, and you can close this PR. I haven't looked into the other packages that were not reproducible, but I suspect the same issue. I will attach a test script that shows the issue if you want to debug it further.
[Bug debug/101473] debug_line info depends on toolchain path
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101473 --- Comment #18 from tonyb at cybernetics dot com --- Created attachment 51181 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51181&action=edit LTO reproducible build test: -ffile-prefix-map in LDFLAGS tar xjf lto-test.tar.bz2 cd lto-test ./run-lto-test FAIL - LTO build is not reproducible edit run-lto-test and change ENABLE_FIX to 1 ./run-lto-test PASS - LTO build is reproducible
[Bug debug/101473] debug_line info depends on toolchain path
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101473 --- Comment #21 from tonyb at cybernetics dot com --- I tried adding -f*-prefix-map to LDFLAGS in Yocto, and that makes everything I tested binary reproducible, except for some shared libraries in /lib and /usr/lib because libtool filters out the -f*-prefix-map flags when linking *.so libraries, but that is not a gcc issue. Since that seems like a viable solution, I will continue the discussion with the Yocto people. Thanks for your help!
[Bug lto/101625] New: ICE in modref_tree::merge with LTO and -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101625 Bug ID: 101625 Summary: ICE in modref_tree::merge with LTO and -m32 Product: gcc Version: 11.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto Assignee: unassigned at gcc dot gnu.org Reporter: tonyb at cybernetics dot com CC: marxin at gcc dot gnu.org Target Milestone: --- Created attachment 51206 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51206&action=edit Relevant *.i preprocessed source files from grub ICE when building grub with LTO. Builds correctly when LTO disabled. gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/home/tonyb/tmp/gcc/install/libexec/gcc/x86_64-pc-linux-gnu/11.1.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc/configure --prefix=/home/tonyb/tmp/gcc/install Thread model: posix Supported LTO compression algorithms: zlib gcc version 11.1.1 20210726 (GCC) gcc -std=gnu99 -Os -m32 -Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2 -march=i386 -mrtd -mregparm=3 -falign-jumps=1 -falign-loops=1 -falign-functions=1 -freg-struct-return -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -msoft-float -fno-dwarf2-cfi-asm -mno-stack-arg-probe -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-ident -fno-stack-protector -Wtrampolines -Werror -ffreestanding -fno-builtin -Wno-undef -flto -ffat-lto-objects -fuse-linker-plugin -save-temps -Wno-error=implicit-fallthrough= -m32 -Wl,-melf_i386 -Wl,--build-id=none -nostdlib -Wl,-N -Wl,-r,-d -flto -ffat-lto-objects -fuse-linker-plugin -o zstd.module lib/zstd/zstd_module-debug.o lib/zstd/zstd_module-entropy_common.o lib/zstd/zstd_module-error_private.o lib/zstd/zstd_module-fse_decompress.o lib/zstd/zstd_module-huf_decompress.o lib/zstd/zstd_module-module.o lib/zstd/zstd_module-xxhash.o lib/zstd/zstd_module-zstd_common.o lib/zstd/zstd_module-zstd_decompress.o during IPA pass: inline lto1: internal compiler error: Segmentation fault 0xadc82f crash_signal ../../gcc/gcc/toplev.c:327 0x90135a modref_tree::merge(modref_tree*, vec*) ../../gcc/gcc/ipa-modref-tree.h:420 0x8f916a ipa_merge_modref_summary_after_inlining(cgraph_edge*) ../../gcc/gcc/ipa-modref.c:3096 0x8ecd94 inline_call(cgraph_edge*, bool, vec*, int*, bool, bool*) ../../gcc/gcc/ipa-inline-transform.c:503 0x1438e56 inline_small_functions ../../gcc/gcc/ipa-inline.c:2242 0x1438e56 ipa_inline ../../gcc/gcc/ipa-inline.c:2723 0x1438e56 execute ../../gcc/gcc/ipa-inline.c:3122
[Bug c/112812] New: Regression: ASAN + stack-protector breaks alignment of stack variables
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112812 Bug ID: 112812 Summary: Regression: ASAN + stack-protector breaks alignment of stack variables Product: gcc Version: 13.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: tonyb at cybernetics dot com Target Milestone: --- Created attachment 56755 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56755&action=edit Test case The combination of -fsanitize=address and -fstack-protector-strong causes gcc 13 to misalign stack variables. Attached is a test program that requests 64-byte alignment of a stack variable. With -fsanitize=address and -fstack-protector-strong, the address is aligned on a 32-byte boundary but not a 64-byte boundary. With other combinations of options the alignment is correct. Running on x86_64. Compile options: gcc -m64 -Wall -O2 -U_FORTIFY_SOURCE -fstack-protector-strong -fsanitize=address -fno-omit-frame-pointer Test fails with gcc version 13.2.1 20231201 Configured with: ../gcc/configure --host=x86_64-pc-linux-gnu --enable-languages=c I believe gcc 12 did not have this bug. I noticed the problem when UBSan complained about a misaligned pointer which led back to a stack variable after upgrading from gcc 12.3 to gcc 13.2.