Skip to content

STACK_OVERFLOW_CHECK does not work with pthreads #27266

Description

@stevenwdv

-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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions