Skip to content

[WebAssembly] Huge symbol name section in debug build #126919

Open
@stevenwdv

Description

@stevenwdv

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:

static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx,
WasmSectionOrderChecker &Checker) {
Section.Type = readUint8(Ctx);
LLVM_DEBUG(dbgs() << "readSection type=" << Section.Type << "\n");
// When reading the section's size, store the size of the LEB used to encode
// it. This allows objcopy/strip to reproduce the binary identically.
const uint8_t *PreSizePtr = Ctx.Ptr;
uint32_t Size = readVaruint32(Ctx);
Section.HeaderSecSizeEncodingLen = Ctx.Ptr - PreSizePtr;
Section.Offset = Ctx.Ptr - Ctx.Start;

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions