Description
Problem
I'm getting a huge (10 GiB) name
section containing symbols in our WebAssembly build, and I don't know if this is a bug or not, since with native builds the section is much smaller (323 MiB for the full binary).
More context
It's so big that WasmObjectFile
cannot successfully parse it anymore: the section is 10 GiB, which does not fit in a uint32, which causes LEB is outside Varuint32 range
when reading, which happens in a llvm-objcopy
command executed at the very last step of linking. This happens with with 32-bit and 64-bit builds.
I first thought this was #58555, but it appears that that is a different issue, my issue happens here:
llvm-project/llvm/lib/Object/WasmObjectFile.cpp
Lines 305 to 314 in 560149b
Stack trace using Debug LLVM build
$ ~/llvm-project/build/bin/llvm-objcopy cpp/pep/cli/pepcli.wasm cpp/pep/cli/pepcli-noproducers.wasm --remove-section=producers
LLVM ERROR: LEB is outside Varuint32 range
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: /home/swdv/llvm-project/build/bin/llvm-objcopy cpp/pep/cli/pepcli.wasm cpp/pep/cli/pepcli.wasm --remove-section=producers
#0 0x00007e9a0cc06f31 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/swdv/llvm-project/llvm/lib/Support/Unix/Signals.inc:804:11
#1 0x00007e9a0cc0742b PrintStackTraceSignalHandler(void*) /home/swdv/llvm-project/llvm/lib/Support/Unix/Signals.inc:880:1
#2 0x00007e9a0cc05426 llvm::sys::RunSignalHandlers() /home/swdv/llvm-project/llvm/lib/Support/Signals.cpp:105:5
#3 0x00007e9a0cc07bed SignalHandler(int, siginfo_t*, void*) /home/swdv/llvm-project/llvm/lib/Support/Unix/Signals.inc:418:7
#4 0x00007e9a0c045330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#5 0x00007e9a0c09eb2c pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x9eb2c)
#6 0x00007e9a0c04527e raise (/lib/x86_64-linux-gnu/libc.so.6+0x4527e)
#7 0x00007e9a0c0288ff abort (/lib/x86_64-linux-gnu/libc.so.6+0x288ff)
#8 0x00007e9a0caca9b4 llvm::report_fatal_error(llvm::Twine const&, bool) /home/swdv/llvm-project/llvm/lib/Support/ErrorHandling.cpp:126:5
#9 0x00007e9a0caca822 /home/swdv/llvm-project/llvm/lib/Support/ErrorHandling.cpp:84:3
#10 0x00007e9a0d5b9699 readVaruint32(llvm::object::WasmObjectFile::ReadContext&) /home/swdv/llvm-project/llvm/lib/Object/WasmObjectFile.cpp:160:10
#11 0x00007e9a0d5b6602 readSection(llvm::object::WasmSection&, llvm::object::WasmObjectFile::ReadContext&, llvm::object::WasmSectionOrderChecker&) /home/swdv/llvm-project/llvm/lib/Object/WasmObjectFile.cpp:312:12
#12 0x00007e9a0d5b63d7 llvm::object::WasmObjectFile::WasmObjectFile(llvm::MemoryBufferRef, llvm::Error&) /home/swdv/llvm-project/llvm/lib/Object/WasmObjectFile.cpp:377:10
#13 0x00007e9a0d5c04d2 std::__detail::_MakeUniq<llvm::object::WasmObjectFile>::__single_object std::make_unique<llvm::object::WasmObjectFile, llvm::MemoryBufferRef&, llvm::Error&>(llvm::MemoryBufferRef&, llvm::Error&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:1070:34
#14 0x00007e9a0d5b5e2f llvm::object::ObjectFile::createWasmObjectFile(llvm::MemoryBufferRef) /home/swdv/llvm-project/llvm/lib/Object/WasmObjectFile.cpp:69:7
#15 0x00007e9a0d58fcbf llvm::object::ObjectFile::createObjectFile(llvm::MemoryBufferRef, llvm::file_magic, bool) /home/swdv/llvm-project/llvm/lib/Object/ObjectFile.cpp:203:12
#16 0x00007e9a0d5a1f50 llvm::object::SymbolicFile::createSymbolicFile(llvm::MemoryBufferRef, llvm::file_magic, llvm::LLVMContext*, bool) /home/swdv/llvm-project/llvm/lib/Object/SymbolicFile.cpp:71:12
#17 0x00007e9a0d400b65 llvm::object::createBinary(llvm::MemoryBufferRef, llvm::LLVMContext*, bool) /home/swdv/llvm-project/llvm/lib/Object/Binary.cpp:78:12
#18 0x00007e9a0d40106f llvm::object::createBinary(llvm::StringRef, llvm::LLVMContext*, bool) /home/swdv/llvm-project/llvm/lib/Object/Binary.cpp:117:8
#19 0x00005dbea7d09645 executeObjcopy(llvm::objcopy::ConfigManager&) /home/swdv/llvm-project/llvm/tools/llvm-objcopy/llvm-objcopy.cpp:173:10
#20 0x00005dbea7d08ee6 llvm_objcopy_main(int, char**, llvm::ToolContext const&) /home/swdv/llvm-project/llvm/tools/llvm-objcopy/llvm-objcopy.cpp:253:15
#21 0x00005dbea7d0d385 main /home/swdv/llvm-project/build/tools/llvm-objcopy/llvm-objcopy-driver.cpp:17:3
#22 0x00007e9a0c02a1ca (/lib/x86_64-linux-gnu/libc.so.6+0x2a1ca)
#23 0x00007e9a0c02a28b __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28b)
#24 0x00005dbea7cc2845 _start (/home/swdv/llvm-project/build/bin/llvm-objcopy+0x34845)
Aborted (core dumped)
It seems that the reading code is correct, see #58555 (comment). However, my question is: how did this section get this large in the first place?
I'm compiling with Release versions of the libraries we use, but compiling our own code as Debug. In the name
section I can see symbol names upwards of 20 MB. (These contain lots of templates and repeated expanded types, also containing type_traits stuff etc. We use RxCpp, which uses a lot of nested templates, causing large symbol names, so that contributes to the problem.) I found that a workaround is to use --strip-all
.
Still, why is this a problem with WebAssembly, and not so much with native builds, which just produce builds of around 323 MiB instead of the 10 GiB we get with WebAssembly?
Might be related to emscripten-core/emscripten#6904 but probably not.