llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.04k stars 11.58k forks source link

lld-10 (and master) crashes when uses profile data from incompatible run #44981

Open trofi opened 4 years ago

trofi commented 4 years ago
Bugzilla Link 45636
Version unspecified
OS Linux
CC @smithp35

Extended Description

It's an extracted version of https://bugs.gentoo.org/718632 where firefox being built under ccache causes llvm to SIGSEGV.

ccache's hegative caching will be fixed in https://github.com/ccache/ccache/issues/582. LLVM's behaviour was to SIGSEGVs when using inconsistent profiling data.

I think it should validate input instead and exit with error.

Also reproducible on LLVM from master. Built llvm master on x86_64-pc-linux-gnu as:

$ cmake -DLLVM_ENABLE_PROJECTS='llvm;lld' -DLLVM_BINUTILS_INCDIR=/usr/include -G "Unix Makefiles" ../llvm && make

The crash is:

real 0m7.403s user 0m25.908s sys 0m0.178s

trofi commented 4 years ago

Sent https://reviews.llvm.org/D79140 for review.

trofi commented 4 years ago

Program aborted due to an unhandled Error: linking module flags 'ProfileSummary': IDs have conflicting values in 'Mutex_posix.o' and 'nsBrowserApp.o'

The cosmetic "unhandled Error" error handling is fixed in https://github.com/llvm/llvm-project/commit/09684b08d3b56b8ab0adb8fe46f709aeba29cee6

Actual error handling of bad input is to be fixed:

Expected FunctionImporter::importFunctions( // ... if (Error Err = Mover.move( std::move(SrcModule), GlobalsToImport.getArrayRef(), [](GlobalValue &, IRMover::ValueAdder) {}, /IsPerformingImport=/true)) report_fatal_error("Function Import: link error: " + toString(std::move(Err)));

need to figure out why report_fatal_error() is called here.

I guess previous code is not prepared to handle failures and was supposed to validate the input.

trofi commented 4 years ago

I also uploaded fully selfcontained example at https://dev.gentoo.org/~slyfox/bugs/llvm-lto-45636/llvm-lld-crash.tar.gz (40MB!)

Steps to reproduce:

  1. clone llvm-project

  2. build llvm, lld and LLVMgold as:

    $ cmake -DLLVM_ENABLE_PROJECTS='llvm;lld' -DLLVM_BINUTILS_INCDIR=/usr/include -G "Unix Makefiles" ../llvm

  3. tweak path to built llvm in 'bug-master.bash'

    change to your path

    llvm_root="${HOME}"/dev/git/llvm-project/build/

  4. run ./bug-master.bash and get SIGSEGV in #comment1

./bug-master.bash is a raw command to lld:

cmd=(
"${llvm_root}"/bin/ld.lld
--eh-frame-hdr -m elf_x86_64
-dynamic-linker ./ld-linux-x86-64.so.2
-o firefox
...
-plugin "${llvm_root}"/lib/LLVMgold.so
...
-plugin-opt=cs-profile-path=./merged.profdata
...

All the needed libraries including crt, lib and libstdc++ are in the archive.

$ sha256sum llvm-lld-crash.tar.gz 8acdabe07515e8d24982778eb20d6ee094f4939bd3609a45340f5358b462c8d0 llvm-lld-crash.tar.gz