Skip to content

wasm-ld crashes on static library + flto #18651

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
gl84 opened this issue Feb 2, 2023 · 3 comments
Open

wasm-ld crashes on static library + flto #18651

gl84 opened this issue Feb 2, 2023 · 3 comments

Comments

@gl84
Copy link
Contributor

gl84 commented Feb 2, 2023

Building a static library with two object files leads to a wasm-ld crash. The crash can be reproduced without any linking to boost libraries (using a >= 1.80 version). For boost <= 1.79 everything works.

Version of emscripten/emsdk:

> emcc --version
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.32-git (36c194dfff84504434f8db4b8161071fa71f6c97)
Copyright (C) 2014 the Emscripten authors (see AUTHORS.txt)
This is free and open source software under the MIT license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Here is a simple repro case:
reader.hpp:

struct reader {
    public:
        reader() {}
        ~reader();
};

reader.cpp:

#include "reader.hpp"
#include <boost/filesystem.hpp>
reader::~reader() {}

exported_api.cpp:

#include "emscripten.h"
#include <boost/filesystem.hpp>
#include "reader.hpp"
extern "C" {
    EMSCRIPTEN_KEEPALIVE void reader_destroy(reader* r) {
        delete r;
    }
}

Building the object files, using emar to combine them and finally producing a side module leads to a wasm-ld crash:
emcc -flto -O0 -o exported_api.cpp.o -c exported_api.cpp -I/home/user/boost_1.80_headers/
emcc -flto -O0 -o reader.cpp.o -c reader.cpp -I/home/user/boost_1.80_headers/
emar -rcs lib_combined.a reader.cpp.o exported_api.cpp.o
emcc -O3 -o lib.wasm lib_combined.a -sSIDE_MODULE=2 -sEXPORTED_FUNCTIONS=[_reader_destroy]

Rerunning the wasm-ld part with --verbose gives:

wasm-ld: Loading: lib_combined.a
wasm-ld: Processing: lib_combined.a
wasm-ld: Processing: lib_combined.a(exported_api.cpp.o)
wasm-ld: Processing: lib_combined.a(reader.cpp.o)
wasm-ld: -- createOutputSegments
wasm-ld: -- createSyntheticSections
wasm-ld: -- layoutMemory
wasm-ld: mem: global base = 0
wasm-ld: mem: .bss            offset=0        size=28       align=2
wasm-ld: mem: static data = 28
wasm-ld: mem: total pages = 1
wasm-ld: -- populateTargetFeatures
wasm-ld: Allowed feature: mutable-globals
wasm-ld: Allowed feature: sign-ext
wasm-ld: -- combineOutputSegments
wasm-ld: -- createSyntheticSectionsPostLayout
wasm-ld: -- populateProducers
wasm-ld: -- calculateImports
wasm-ld: -- scanRelocations
wasm-ld: -- finalizeIndirectFunctionTable
wasm-ld: -- createSyntheticInitFunctions
wasm-ld: -- assignIndexes
wasm-ld: -- calculateInitFunctions
wasm-ld: /b/s/w/ir/cache/builder/emscripten-releases/llvm-project/llvm/include/llvm/Support/Casting.h:579: decltype(auto) llvm::cast(From *) [To = lld::wasm::DefinedFunction, From = const lld::wasm::FunctionSymbol]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: /home/user/emsdk_tot/emsdk/upstream/bin/wasm-ld --verbose -o lib.wasm lib_combined.a -L/home/user/emsdk_tot/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/pic -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-undefined --import-memory --strip-debug --export-if-defined=reader_destroy --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=__wasm_apply_data_relocs --export=__wasm_call_ctors --experimental-pic -shared --no-export-dynamic
 #0 0x00007f6271acf788 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/user/emsdk_tot/emsdk/upstream/bin/../lib/libLLVM-17git.so+0x1b73788)
 #1 0x00007f6271acd62e llvm::sys::RunSignalHandlers() (/home/user/emsdk_tot/emsdk/upstream/bin/../lib/libLLVM-17git.so+0x1b7162e)
 #2 0x00007f6271acff3d SignalHandler(int) Signals.cpp:0:0
 #3 0x00007f626fb36520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007f626fb8aa7c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007f626fb8aa7c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x00007f626fb8aa7c pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x00007f626fb36476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007f626fb1c7f3 abort ./stdlib/abort.c:81:7
 #9 0x00007f626fb1c71b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x00007f626fb2de96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#11 0x0000561084c02306 (/home/user/emsdk_tot/emsdk/upstream/bin/wasm-ld+0x4ce306)
#12 0x0000561084c0b4a8 lld::wasm::(anonymous namespace)::Writer::run() Writer.cpp:0:0
#13 0x0000561084c03926 lld::wasm::writeResult() (/home/user/emsdk_tot/emsdk/upstream/bin/wasm-ld+0x4cf926)
#14 0x0000561084be0e24 lld::wasm::(anonymous namespace)::LinkerDriver::linkerMain(llvm::ArrayRef<char const*>) Driver.cpp:0:0
#15 0x0000561084bdde05 lld::wasm::link(llvm::ArrayRef<char const*>, llvm::raw_ostream&, llvm::raw_ostream&, bool, bool) (/home/user/emsdk_tot/emsdk/upstream/bin/wasm-ld+0x4a9e05)
#16 0x00005610848d2577 lldMain(int, char const**, llvm::raw_ostream&, llvm::raw_ostream&, bool) lld.cpp:0:0
#17 0x00005610848d1d9c lld_main(int, char**) (/home/user/emsdk_tot/emsdk/upstream/bin/wasm-ld+0x19dd9c)
#18 0x00007f626fb1dd90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#19 0x00007f626fb1de40 call_init ./csu/../csu/libc-start.c:128:20
#20 0x00007f626fb1de40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#21 0x00005610848d18aa _start (/home/user/emsdk_tot/emsdk/upstream/bin/wasm-ld+0x19d8aa)

Using the object files directly, removing flto or using boost < 1.80 works as expected.

@sbc100
Copy link
Collaborator

sbc100 commented Feb 2, 2023

Does this issue still happen if you build without -sSIDE_MODULE=2 ?

BTW, normally when building a side module (or code that gets dynamically linked) you would compiler the sources with -fPIC. Does doing that help in this case?

@gl84
Copy link
Contributor Author

gl84 commented Feb 2, 2023

fPIC doesn't make a difference, flto is needed to reproduce the crash.

The crash also occurs without -sSIDE_MODULE=2 (if I add a dummy main to exported_api.cpp)

@sbc100
Copy link
Collaborator

sbc100 commented Oct 3, 2023

I just updated our boost port to 1.80 and then 1.83 and I was not able to reproduce the issue. (See #20384).

Here is the script I used:

emcc -flto -O0 -o exported_api.cpp.o -c exported_api.cpp -sUSE_BOOST_HEADERS
emcc -flto -O0 -o reader.cpp.o -c reader.cpp -sUSE_BOOST_HEADERS 
emar -rcs  lib_combined.a reader.cpp.o exported_api.cpp.o
emcc -O3 -o lib.wasm lib_combined.a  -sSIDE_MODULE=2 -sEXPORTED_FUNCTIONS=_reader_destroy -sUSE_BOOST_HEADERS

I don't get a crash on linking.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants