Skip to content

Stack Size defaults not honored in web workers starting in 3.1.35 #19573

@jnickg

Description

@jnickg

Trying to update a large project to the latest EMSDK version, and I discovered some strange behavior. As late as EMSDK 3.1.34, the threads instantiated by my wasm module (which is spun up in a web worker) roughly honored flags like STACK_SIZE PKA TOTAL_STACK, and DEFAULT_PTHREAD_STACK_SIZE. For example, if I set DEFAULT_PTHREAD_STACK_SIZE=2MB I would see via PTHREADS_DEBUG instrumentation that the stack range shown by establishStackSpace messages was the correct amount. Sometimes values deviated, I'm guessing due to heuristics or something, but generally they were in the order of magnitude I requested, so it appeared the system was attempting to honor the given flags.

Starting in 3.1.35, threads made through the raw pthread interface stopped honoring this. Perhaps related to this line of code? I am guessing is_main evaluates to false on a web worker. Instead the stack size was 64 KiB (perhaps related to this change?) However, threads started up via the std::thread interface still had the correct stack sizes.

Then, starting in 3.1.39, for reasons I am still unsure of, threads started via std::thread (which BTW has no interface for changing stack size programmatically) ALSO started ignoring stack-size flags. The stack was instead 64 KiB.

Full link command (some of them are artifacts from a CMake dependency with public link flags, included below for completeness):

/path/to/emsdk/upstream/emscripten/em++  \
    -Wno-deprecated-copy -Wno-deprecated-declarations \
    -Wno-inconsistent-missing-override -Wno-unknown-pragmas \
    -Wno-unused-local-typedef -Wno-int-in-bool-context \
    -Wno-implicit-function-declaration -Wno-missing-prototypes \
    -Wno-reorder -Wno-shadow -Wno-shorten-64-to-32 \
    -Wno-sign-compare -Wno-unreachable-code \
    -Wno-unused-parameter -Wno-unused-private-field \
    -Wno-unused-variable -Wno-deprecated-non-prototype \
    -Wno-unused-command-line-argument \
    -Wno-pthreads-mem-growth \
    -std=c++20 -fexceptions -frtti -fwasm-exceptions -fPIC \
    -pthread -msimd128 -msse -msse2 -msse3 -DNDEBUG \
    -Oz -fno-inline-functions \
    @CMakeFiles/my_module.dir/objects1.rsp -o my_module.js \ # not dereferencing since it's probably not relevant
     -sEXPORT_NAME=MyModule \
    -sENVIRONMENT=worker \
    -sEXPORTED_FUNCTIONS=_malloc,_free,_main \
    <my_.a_files_to_link> \
    -ldl --bind -sMODULARIZE=1 -sEXPORT_ES6=1 \
    -sSTACK_SIZE=10485760 -sINITIAL_MEMORY=100mb \
    -sALLOW_MEMORY_GROWTH=1 \
    -sERROR_ON_UNDEFINED_SYMBOLS=1 -sSTRICT=1 \
    -sEXPORTED_RUNTIME_METHODS=[ccall,FS,addFunction,getValue] \
    -sALLOW_TABLE_GROWTH -sFORCE_FILESYSTEM 
    -sWASM_BIGINT -sALLOW_UNIMPLEMENTED_SYSCALLS=1 \
    -sPTHREAD_POOL_SIZE=14 -sPTHREAD_POOL_SIZE_STRICT=0 \
    -sDEFAULT_PTHREAD_STACK_SIZE=524288 

Extra detail: In case it's relevant somehow, we are building through CMake. We were updating from 3.1.8, and ran into issues with the latest version. To reproduce this issue, I built/ran our module with different EMSDK versions, changing flags as little as possible. We were able to update to 3.1.34 and get a stable build with the flags above, only having to remove deprecated flags (which I can dig up if you need them), and change TOTAL_STACK to STACK_SIZE.

You can probably guess, but we use large stack values because our software makes ample use of stack space. Which means that when it's ignored and set to 64 KiB, we quickly crash. Where exactly we crash varies since this is related to threading, but it was usually when locking a mutex, creating another thread, or calling pthread_getspecific()/pthread_setspecific()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions