emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.36k stars 3.25k forks source link

Stack overflow in AudioWorkletNode when -O0 #22070

Closed tadashibashi closed 1 week ago

tadashibashi commented 3 weeks ago

Hi, I'm encountering an issue where in the audio callback of an AudioWorkletNode, when optimization is set to -O0 and I call a recursive mixing function, it throws a stack overflow error in-browser (testing in Chrome and Safari). The thing is that this does not happen when setting optimization to -O1 or higher, calling the function in an Emscripten pthread with -O0, or on desktop (AppleClang 15) with -O0.

Here's the specific error message: Aborted(Stack overflow! Stack cookie has been overwritten at 0x00000004, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x89bacdfe 0x000b3f5c)

I've also tried

For now, setting the optimization level to -O1 appears to be a temporary solution, but it would be great to discover what the actual issue might be.

Version of emscripten/emsdk: emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.61 (67fa4c16496b157a7fc3377afd69ee0445e8a6e3) clang version 19.0.0git (https:/github.com/llvm/llvm-project 7cfffe74eeb68fbb3fb9706ac7071f8caeeb6520) Target: wasm32-unknown-emscripten Thread model: posix

Failing command line in full: Using the cmake toolchain, these flags are set:

Link flags: -O0 -g -gsource-map -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=2GB -sSTACK_SIZE=131072 -sAUDIO_WORKLET=1 -sWASM_WORKERS=1 -pthread -sPTHREAD_POOL_SIZE=4 -sASSERTIONS=2 -sWASM=1

Compile flags: -pthread --preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@assets

Output suffix: .html

I'm also building and statically linking SDL 2.30.3 with pthreads on, instead of using the emscripten port

juj commented 3 weeks ago

How large of a stack are you allocating when calling emscripten_start_wasm_audio_worklet_thread_async? Try allocating something excessive, like 32MB for the stack size, does that change anything?

I call a recursive mixing function

How many levels of recursion do you have when the stack overflows? Can you try to see if artifically capping the recursion depth affects the situation?

-O1 or higher removing an issue with recursion is not unheard of, since what can happen is that LLVM optimizes away all variable spills, resulting in the LLVM stack not being used at all (or less) by the recursive function.

tadashibashi commented 2 weeks ago

I just tried allocating 32MB when calling emscripten_start_wasm_audio_worklet_thread_async with the same result.

Currently there are only two levels of depth, which seems strange that a stack overflow should happen. Reducing it to only one level has the same result. What's also interesting is that calling the function in the main thread or in a pthread doesn't throw the error.

It might take some time, but if I can isolate the problem in a minimal repro, I'll post it.

tadashibashi commented 1 week ago

It's hard to say what the problem was - I tried refactoring using wasm simd, and either that solved it or some other bug was fixed during the rewrite.