emscripten-core / emscripten-core/emscripten
dlopen + std::thread
- Dominant language
- C++
- Stars
- 27.6k
- Forks
- 3.6k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 105
Description
**Version of emscripten/emsdk:**
```
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.34 (57b21b8fdcbe3ebb523178b79465254668eab408)
clang version 17.0.0 (https://github.com/llvm/llvm-project a031f72187ce495b9faa4ccf99b1e901a3872f4b)
Target: wasm32-unknown-emscripten
Thread model: posix
```
**Failing command line in full:**
```
node --experimental-wasm-threads --experimental-wasm-bulk-memory main2.js
```
**Full link command and output with `-v` appended:**
```
"C:/work/git/emsdk/upstream/bin\clang.exe" --version
"C:/work/git/emsdk/upstream/bin\clang++.exe" -target wasm32-unknown-emscripten -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-cxx-exceptions -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -D__EMSCRIPTEN_SHARED_MEMORY__=1 -DEMSCRIPTEN --sysroot=C:\work\git\emsdk\upstream\emscripten\cache\sysroot -Xclang -iwithsysroot/include\fakesdl -Xclang -iwithsysroot/include\compat -O1 -fPIC -fexceptions -pthread -v -matomics -mbulk-memory main2.cpp -c -o C:\Users\JUKKA~1.LII\AppData\Local\Temp\emscripten_temp_620n_5ro\main2_0.o
clang version 17.0.0 (https://github.com/llvm/llvm-project a031f72187ce495b9faa4ccf99b1e901a3872f4b)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: C:\work\git\emsdk\upstream\bin
(in-process)
"C:\\work\\git\\emsdk\\upstream\\bin\\clang++.exe" -cc1 -triple wasm32-unknown-emscripten -emit-obj -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main2.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-feature +atomics -target-feature +bulk-memory -target-feature +mutable-globals -target-feature +sign-ext -target-feature +mutable-globals -target-cpu generic -target-feature +atomics -target-feature +bulk-memory -mllvm -treat-scalable-fixed-error-as-warning -debugger-tuning=gdb -v "-fcoverage-compilation-dir=C:\\work\\temp\\code\\simple" -resource-dir "C:\\work\\git\\emsdk\\upstream\\lib\\clang\\17" -D __EMSCRIPTEN_SHARED_MEMORY__=1 -D EMSCRIPTEN -isysroot "C:\\work\\git\\emsdk\\upstream\\emscripten\\cache\\sysroot" -internal-isystem "C:\\work\\git\\emsdk\\upstream\\emscripten\\cache\\sysroot/include/wasm32-emscripten/c++/v1" -internal-isystem "C:\\work\\git\\emsdk\\upstream\\emscripten\\cache\\sysroot/include/c++/v1" -internal-isystem "C:\\work\\git\\emsdk\\upstream\\lib\\clang\\17\\include" -internal-isystem "C:\\work\\git\\emsdk\\upstream\\emscripten\\cache\\sysroot/include/wasm32-emscripten" -internal-isystem "C:\\work\\git\\emsdk\\upstream\\emscripten\\cache\\sysroot/include" -O1 -fdeprecated-macro "-fdebug-compilation-dir=C:\\work\\temp\\code\\simple" -ferror-limit 19 -fmessage-length=125 -fvisibility=default -pthread -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fcolor-diagnostics "-iwithsysroot/include\\fakesdl" "-iwithsysroot/include\\compat" -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-cxx-exceptions -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -o "C:\\Users\\JUKKA~1.LII\\AppData\\Local\\Temp\\emscripten_temp_620n_5ro\\main2_0.o" -x c++ main2.cpp
clang -cc1 version 17.0.0 based upon LLVM 17.0.0git default target x86_64-pc-windows-msvc
ignoring nonexistent directory "C:\work\git\emsdk\upstream\emscripten\cache\sysroot/include/wasm32-emscripten/c++/v1"
ignoring nonexistent directory "C:\work\git\emsdk\upstream\emscripten\cache\sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
C:\work\git\emsdk\upstream\emscripten\cache\sysroot/include\fakesdl
C:\work\git\emsdk\upstream\emscripten\cache\sysroot/include\compat
C:\work\git\emsdk\upstream\emscripten\cache\sysroot/include/c++/v1
C:\work\git\emsdk\upstream\lib\clang\17\include
C:\work\git\emsdk\upstream\emscripten\cache\sysroot/include
End of search list.
em++: warning: -sMAIN_MODULE + pthreads is experimental [-Wexperimental]
"C:/work/git/emsdk/upstream/bin\wasm-ld.exe" -o main2.wasm --whole-archive C:\Users\JUKKA~1.LII\AppData\Local\Temp\emscripten_temp_620n_5ro\main2_0.o -LC:\work\git\emsdk\upstream\emscripten\cache\sysroot\lib\wasm32-emscripten\pic C:\work\git\emsdk\upstream\emscripten\cache\sysroot\lib\wasm32-emscripten\pic\crtbegin.o -lGL-mt -lal -lhtml5 -lstubs -lnoexit -lc-mt -ldlmalloc-mt -lcompiler_rt-mt -lc++-mt -lc++abi-mt -lsockets-mt --no-whole-archive -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-cxx-exceptions -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --allow-undefined-file=C:\Users\JUKKA~1.LII\AppData\Local\Temp\tmp2t1p7e9k.undefined --import-memory --shared-memory --export-dynamic --export-if-defined=main --export-if-defined=_emscripten_thread_init --export-if-defined=_emscripten_thread_exit --export-if-defined=_emscripten_thread_crashed --export-if-defined=_emscripten_tls_init --export-if-defined=pthread_self --export-if-defined=__get_exception_message --export-if-defined=free --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=__main_argc_argv --export-if-defined=__wasm_apply_data_relocs --export=setThrew --export=emscripten_stack_get_base --export=emscripten_stack_get_end --export=emscripten_stack_set_limits --export=stackSave --export=stackRestore --export=stackAlloc --export=__errno_location --export=emscripten_dispatch_to_thread_ --export=_emscripten_thread_free_data --export=emscripten_main_runtime_thread_id --export=emscripten_main_thread_process_queued_calls --export=_emscripten_run_in_main_runtime_thread_js --export=_emscripten_dlsync_self --export=_emscripten_dlsync_self_async --export=_emscripten_proxy_dlsync --export=_emscripten_proxy_dlsync_async --export=__dl_seterr --export=getTempRet0 --export=setTempRet0 --export=__get_temp_ret --export=__set_temp_ret --export=malloc --export=free --export=__cxa_is_pointer_type --export=__cxa_can_catch --export=__cxa_free_exception --export=__wasm_call_ctors --export=_emscripten_timeout --export=ntohs --export=htons --export=saveSetjmp --export=htonl --export=memcpy --export=sleep --export=fileno --export=memcmp --export=pthread_self --export=emscripten_builtin_memalign --experimental-pic -pie -z stack-size=65536 --initial-memory=16777216 --no-entry --max-memory=16777216
"C:/work/git/emsdk/upstream\bin\wasm-emscripten-finalize" --pass-arg=legalize-js-interface-export-originals --pass-arg=legalize-js-interface-exported-helpers main2.wasm -o main2.wasm --detect-features
"C:/work/git/emsdk/node/14.18.2_64bit/bin/node.exe" C:\work\git\emsdk\upstream\emscripten\src\compiler.js C:\Users\JUKKA~1.LII\AppData\Local\Temp\tmpwdihuekm.json
"C:/work/git/emsdk/upstream\bin\wasm-opt" --strip-dwarf --asyncify --pass-arg=asyncify-relocatable --pass-arg=asyncify-imports@env.invoke_*,env.emscripten_sleep,env.emscripten_wget,env.emscripten_wget_data,env.emscripten_idb_load,env.emscripten_idb_store,env.emscripten_idb_delete,env.emscripten_idb_exists,env.emscripten_idb_load_blob,env.emscripten_idb_store_blob,env.SDL_Delay,env.emscripten_scan_registers,env.emscripten_lazy_load_code,env.emscripten_fiber_swap,env.__load_secondary_module,wasi_snapshot_preview1.fd_sync,env.__wasi_fd_sync,env._emval_await,env._dlopen_js,env.__asyncjs__* --strip-debug --strip-producers main2.wasm -o main2.wasm --mvp-features --enable-threads --enable-bulk-memory --enable-mutable-globals --enable-sign-ext
"C:/work/git/emsdk/node/14.18.2_64bit/bin/node.exe" C:\work\git\emsdk\upstream\emscripten\tools\preprocessor.js C:\Users\JUKKA~1.LII\AppData\Local\Temp\emscripten_temp_620n_5ro\settings.js worker.js --expandMacros
"C:/work/git/emsdk/node/14.18.2_64bit/bin/node.exe" C:\work\git\emsdk\upstream\emscripten\tools\acorn-optimizer.js C:\work\temp\code\simple\main2.worker.js minifyWhitespace
```
## problem description
The issue is using std::thread when loading shared object with dlopen. Linking to the same shared object and calling the function where thread is used works, but when loading dynamically and calling the queried functions the code crashes.
```
C:\work\temp\code\simple\main2.js:135
throw ex;
^
RuntimeError: memory access out of bounds
at main (:wasm-function[170]:0x90d8f)
at ret. (C:\work\temp\code\simple\main2.js:16252:35)
at Object.doRewind (C:\work\temp\code\simple\main2.js:16335:16)
at C:\work\temp\code\simple\main2.js:16360:47
at C:\work\temp\code\simple\main2.js:7624:49
```
## source code to reproduce
super.cpp
```
#include
extern "C"
const char* duper_text(int index)
{
if (index > 0)
{
std::thread thread = std::thread([]
{
});
thread.join();
return "Hello, world! (thread)";
}
return "Hello, world! (no thread)";
}
```
main1.cpp
```
#include
extern "C"
const char* duper_text(int);
int main()
{
for (int i = 0; i < 2; ++i)
{
const char* s = duper_text(i);
if (s)
{
printf("Message: \"%s\"\n", s);
}
}
}
```
main2.cpp
```
#include
#include
using DuperFunc = const char* (*)(int);
int main()
{
void* handle = ::dlopen("super.so", RTLD_NOW);
if (!handle)
{
printf("dlopen() failed.\n");
return 0;
}
void* ptr = ::dlsym(handle, "duper_text");
if (ptr)
{
DuperFunc duper = reinterpret_cast(ptr);
for (int i = 0; i < 2; ++i)
{
const char* s = duper(i);
if (s)
{
printf("Message: \"%s\"\n", s);
}
}
}
::dlclose(handle);
}
```
test.bat
```
call em++ super.cpp -o super.so -O1 -sSIDE_MODULE=1 -fPIC -sASYNCIFY -fexceptions -pthread -lpthread
call em++ main1.cpp -o main1.js -O1 -sMAIN_MODULE=1 -fPIC -sASYNCIFY -fexceptions -pthread super.so
call em++ main2.cpp -o main2.js -O1 -sMAIN_MODULE=1 -fPIC -sASYNCIFY -fexceptions -pthread
node --experimental-wasm-threads --experimental-wasm-bulk-memory main1.js
node --experimental-wasm-threads --experimental-wasm-bulk-memory main2.js
```
The tests call duper_text function, which creates a thread when index > 0. The main1 works always. The main2 crashes when creating a thread: "RuntimeError: memory access out of bounds"
## TL;DR
ASYNCIFY + dlopen + std::thread crashes.
Contributor guide
Assessment
This issue has not been assessed yet.