-sSTACK_OVERFLOW_CHECK does not work in a pthread. Instead of a clear "Stack overflow!", you get a random error ("memory access out of bounds" / "table index out of bounds" / "null function or function signature mismatch" / "unreachable executed" / etc.). This makes troubleshooting way harder.
Is this a known limitation? If so, I think it should be documented.
Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 6.0.2 (7a2d97d)
Failing command line in full:
stack-overflow.cpp:
#include <iostream>
#include <thread>
static void stackOverflow(unsigned d) {
std::cout << 'a';
if (!d--) return;
stackOverflow(d);
std::cout << 'b';
}
int main() {
std::jthread([] {
stackOverflow(20'000);
});
}
We compile with STACK_OVERFLOW_CHECK (implicit without optimization):
$ em++ ./stack-overflow.cpp -o ./stack-overflow -pthread -std=c++20 -v
"/home/swdv/emsdk/upstream/bin/clang++" -target wasm32-unknown-emscripten -fignore-exceptions -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/home/swdv/emsdk/upstream/emscripten/cache/sysroot -D__EMSCRIPTEN_SHARED_MEMORY__=1 -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -pthread -std=c++20 -v -c ./stack-overflow.cpp -o /tmp/emscripten_temp_clixitb0/stack-overflow.o
clang version 23.0.0git (https:/github.com/llvm/llvm-project 787619a4072e0eb7887357d5d284e86c17548aed)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/swdv/emsdk/upstream/bin
(in-process)
"/home/swdv/emsdk/upstream/bin/clang-23" -cc1 -triple wasm32-unknown-emscripten -emit-obj -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name stack-overflow.cpp -mrelocation-model static -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-cpu generic -fvisibility=hidden -debugger-tuning=gdb -fdebug-compilation-dir=/home/swdv/Downloads -v -fcoverage-compilation-dir=/home/swdv/Downloads -resource-dir /home/swdv/emsdk/upstream/lib/clang/23 -D __EMSCRIPTEN_SHARED_MEMORY__=1 -isysroot /home/swdv/emsdk/upstream/emscripten/cache/sysroot -internal-isystem /home/swdv/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten/noeh/c++/v1 -internal-isystem /home/swdv/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten/c++/v1 -internal-isystem /home/swdv/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1 -internal-isystem /home/swdv/emsdk/upstream/lib/clang/23/include -internal-isystem /home/swdv/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten -internal-isystem /home/swdv/emsdk/upstream/emscripten/cache/sysroot/include -std=c++20 -fdeprecated-macro -ferror-limit 19 -fmessage-length=214 -pthread -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fignore-exceptions -fexceptions -fcolor-diagnostics -iwithsysroot/include/fakesdl -iwithsysroot/include/compat -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -o /tmp/emscripten_temp_clixitb0/stack-overflow.o -x c++ ./stack-overflow.cpp
clang -cc1 version 23.0.0git based upon LLVM 23.0.0git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/home/swdv/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten/noeh/c++/v1"
ignoring nonexistent directory "/home/swdv/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten/c++/v1"
ignoring nonexistent directory "/home/swdv/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
/home/swdv/emsdk/upstream/emscripten/cache/sysroot/include/fakesdl
/home/swdv/emsdk/upstream/emscripten/cache/sysroot/include/compat
/home/swdv/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1
/home/swdv/emsdk/upstream/lib/clang/23/include
/home/swdv/emsdk/upstream/emscripten/cache/sysroot/include
End of search list.
/home/swdv/emsdk/upstream/bin/clang --version
/home/swdv/emsdk/upstream/bin/wasm-ld -o ./stack-overflow.wasm /tmp/tmphvot3yl6libemscripten_js_symbols.so -Bstatic --import-memory --shared-memory --strip-debug --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_get_base --export=emscripten_stack_get_current --export=emscripten_stack_init --export=_emscripten_stack_alloc --export=_emscripten_thread_free_data --export=_emscripten_thread_crashed --export=__wasm_call_ctors --export=_emscripten_tls_init --export=_emscripten_thread_init --export=pthread_self --export=__set_thread_state --export=_emscripten_stack_restore --export=emscripten_stack_set_limits --export=_emscripten_thread_exit --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 --export-if-defined=__main_argc_argv --export-if-defined=fflush --export-table -z stack-size=65536 --no-growable-memory --initial-memory=16777216 --no-entry --stack-first --table-base=1 /tmp/emscripten_temp_clixitb0/stack-overflow.o -L/home/swdv/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten -L/home/swdv/emsdk/upstream/emscripten/src/lib /home/swdv/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/crtbegin-mt.o -lGL-mt-getprocaddr -lal -lhtml5 -lstubs-debug -lnoexit -lc-mt-debug -ldlmalloc-mt-debug -lclang_rt.builtins-mt -lc++-debug-mt-noexcept -lc++abi-debug-mt-noexcept -lsockets-mt -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr
/home/swdv/emsdk/upstream/bin/llvm-objcopy ./stack-overflow.wasm ./stack-overflow.wasm '--remove-section=llvm.func_attr.annotate.*' --remove-section=producers --remove-section=name '--remove-section=.debug*'
$ ./stack-overflow
worker: onmessage() captured an uncaught exception: RuntimeError: memory access out of bounds
Aborted(native code called abort())
RuntimeError: memory access out of bounds
at wasm://wasm/000caaea:wasm-function[600]:0x115e1
at wasm://wasm/000caaea:wasm-function[599]:0x11505
at wasm://wasm/000caaea:wasm-function[166]:0x4683
at wasm://wasm/000caaea:wasm-function[162]:0x455d
at wasm://wasm/000caaea:wasm-function[157]:0x420a
at wasm://wasm/000caaea:wasm-function[156]:0x40e7
at wasm://wasm/000caaea:wasm-function[155]:0x4069
at wasm://wasm/000caaea:wasm-function[155]:0x4091
at wasm://wasm/000caaea:wasm-function[155]:0x4091
at wasm://wasm/000caaea:wasm-function[155]:0x4091
/home/swdv/Downloads/stack-overflow:834
var e = new WebAssembly.RuntimeError(what);
^
RuntimeError: Aborted(native code called abort())
at abort (/home/swdv/Downloads/stack-overflow:834:11)
at __abort_js (/home/swdv/Downloads/stack-overflow:1716:7)
at wasm://wasm/000caaea:wasm-function[386]:0x8d50
at wasm://wasm/000caaea:wasm-function[429]:0xd564
at wasm://wasm/000caaea:wasm-function[318]:0x7a40
at /home/swdv/Downloads/stack-overflow:848:12
at Object.returnWorkerToPool (/home/swdv/Downloads/stack-overflow:1282:9)
at cleanupThread (/home/swdv/Downloads/stack-overflow:1063:15)
at __emscripten_thread_cleanup (/home/swdv/Downloads/stack-overflow:1894:36)
at wasm://wasm/000caaea:wasm-function[1270]:0x2d1be
Node.js v22.16.0
This also happens with -sPROXY_TO_PTHREAD.
Compare with what happens without the thread:
./stack-overflow
Aborted(Stack overflow! Stack cookie has been overwritten at 0x00000004, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x00000000 0x00000000)
/home/swdv/Downloads/stack-overflow:834
var e = new WebAssembly.RuntimeError(what);
^
RuntimeError: Aborted(Stack overflow! Stack cookie has been overwritten at 0x00000004, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x00000000 0x00000000)
at abort (/home/swdv/Downloads/stack-overflow:834:11)
at checkStackCookie (/home/swdv/Downloads/stack-overflow:364:5)
at handleException (/home/swdv/Downloads/stack-overflow:1691:7)
at callMain (/home/swdv/Downloads/stack-overflow:5539:12)
at run (/home/swdv/Downloads/stack-overflow:5590:22)
at /home/swdv/Downloads/stack-overflow:5642:25
Node.js v22.16.0
-sSTACK_OVERFLOW_CHECKdoes not work in a pthread. Instead of a clear "Stack overflow!", you get a random error ("memory access out of bounds" / "table index out of bounds" / "null function or function signature mismatch" / "unreachable executed" / etc.). This makes troubleshooting way harder.Is this a known limitation? If so, I think it should be documented.
Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 6.0.2 (7a2d97d)
Failing command line in full:
stack-overflow.cpp:We compile with
STACK_OVERFLOW_CHECK(implicit without optimization):This also happens with
-sPROXY_TO_PTHREAD.Compare with what happens without the thread: