Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generated Wasm module fails with "stack overflow" / "memory access out of bounds" (nodejs runtime error) #21848

Closed
mkarup opened this issue Apr 29, 2024 · 2 comments

Comments

@mkarup
Copy link

mkarup commented Apr 29, 2024

I have some C code generated through the CertiCoq project.
Emscripten produces a Wasm module that fails with a stack overflow/ memory access out of bounds runtime error when trying to run the module via the generated js scaffolding and nodejs (v.20.12.2).

The x86-64 binary runs without issues.

I have attached a zip containing the C files needed for running the emcc command:
sm_gauss_nat.zip

Error message for command node --stack-size=1000000 sm_gauss_nat-opt_O0.js:

Stack overflow detected.  You can try increasing -sSTACK_SIZE (currently set to 100000)
/home/martin/Documents/sm_gauss_nat/sm_gauss_nat-opt_O0.js:132
      throw ex;
      ^

RuntimeError: memory access out of bounds
    at sm_gauss_nat-opt_O0.wasm.s_compile_uncurried_uncurried_known_119 (wasm://wasm/sm_gauss_nat-opt_O0.wasm-000c23d6:wasm-function[34]:0x6659)
    at sm_gauss_nat-opt_O0.wasm.s_compile_uncurried_uncurried_known_119 (wasm://wasm/sm_gauss_nat-opt_O0.wasm-000c23d6:wasm-function[34]:0x6bfb)
    at sm_gauss_nat-opt_O0.wasm.s_compile_uncurried_uncurried_known_119 (wasm://wasm/sm_gauss_nat-opt_O0.wasm-000c23d6:wasm-function[34]:0x6d3a)
    at sm_gauss_nat-opt_O0.wasm.s_compile_uncurried_uncurried_known_119 (wasm://wasm/sm_gauss_nat-opt_O0.wasm-000c23d6:wasm-function[34]:0x6d3a)
    at sm_gauss_nat-opt_O0.wasm.s_compile_uncurried_uncurried_known_119 (wasm://wasm/sm_gauss_nat-opt_O0.wasm-000c23d6:wasm-function[34]:0x6d3a)
    at sm_gauss_nat-opt_O0.wasm.s_compile_uncurried_uncurried_known_119 (wasm://wasm/sm_gauss_nat-opt_O0.wasm-000c23d6:wasm-function[34]:0x6d3a)
    at sm_gauss_nat-opt_O0.wasm.s_compile_uncurried_uncurried_known_119 (wasm://wasm/sm_gauss_nat-opt_O0.wasm-000c23d6:wasm-function[34]:0x6d3a)
    at sm_gauss_nat-opt_O0.wasm.s_compile_uncurried_uncurried_known_119 (wasm://wasm/sm_gauss_nat-opt_O0.wasm-000c23d6:wasm-function[34]:0x6d3a)
    at sm_gauss_nat-opt_O0.wasm.s_compile_uncurried_uncurried_known_119 (wasm://wasm/sm_gauss_nat-opt_O0.wasm-000c23d6:wasm-function[34]:0x6d3a)
    at sm_gauss_nat-opt_O0.wasm.s_compile_uncurried_uncurried_known_119 (wasm://wasm/sm_gauss_nat-opt_O0.wasm-000c23d6:wasm-function[34]:0x6d3a)

Node.js v20.12.2

Adding optimization flags doesn't seem to help, and increasing the stack size seems to cause a segmentation fault for me when trying to run with node.

Emscripten Version

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.58 (a41843e0860e52c948c1fce20307933c6631c800)
clang version 19.0.0git (https:/github.com/llvm/llvm-project 0a8cd1ed1f4f35905df318015b0dbcb69d81d7c2)
Target: wasm32-unknown-emscripten
Thread model: posix

Full command:

emcc -v -O0 -o sm_gauss_nat-opt_O0.js -w -Wno-everything -I./ sm_gauss_nat_main_wasm.c gc_stack.c CertiCoq.Benchmarks.tests.sm_gauss_nat.c glue_sm_gauss_nat.c -sALLOW_MEMORY_GROWTH=1 -sSTACK_SIZE=100000 --profiling

Output:

 /home/martin/code/emsdk/upstream/bin/clang -target wasm32-unknown-emscripten -fignore-exceptions -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/home/martin/code/emsdk/upstream/emscripten/cache/sysroot -DEMSCRIPTEN -Werror=implicit-function-declaration -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -v -O0 -w -Wno-everything -I./ sm_gauss_nat_main_wasm.c -c -o /tmp/emscripten_temp_ald21kk8/sm_gauss_nat_main_wasm_0.o
clang version 19.0.0git (https:/github.com/llvm/llvm-project 0a8cd1ed1f4f35905df318015b0dbcb69d81d7c2)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/martin/code/emsdk/upstream/bin
 (in-process)
 "/home/martin/code/emsdk/upstream/bin/clang-19" -cc1 -triple wasm32-unknown-emscripten -emit-obj -mrelax-all -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name sm_gauss_nat_main_wasm.c -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/martin/Documents/sm_gauss_nat -v -fcoverage-compilation-dir=/home/martin/Documents/sm_gauss_nat -resource-dir /home/martin/code/emsdk/upstream/lib/clang/19 -D EMSCRIPTEN -I ./ -isysroot /home/martin/code/emsdk/upstream/emscripten/cache/sysroot -internal-isystem /home/martin/code/emsdk/upstream/lib/clang/19/include -internal-isystem /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten -internal-isystem /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include -O0 -Werror=implicit-function-declaration -Wno-everything -w -ferror-limit 19 -fvisibility=default -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fignore-exceptions -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_ald21kk8/sm_gauss_nat_main_wasm_0.o -x c sm_gauss_nat_main_wasm.c
clang -cc1 version 19.0.0git based upon LLVM 19.0.0git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
 .
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/fakesdl
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/compat
 /home/martin/code/emsdk/upstream/lib/clang/19/include
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include
End of search list.
 /home/martin/code/emsdk/upstream/bin/clang -target wasm32-unknown-emscripten -fignore-exceptions -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/home/martin/code/emsdk/upstream/emscripten/cache/sysroot -DEMSCRIPTEN -Werror=implicit-function-declaration -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -v -O0 -w -Wno-everything -I./ gc_stack.c -c -o /tmp/emscripten_temp_ald21kk8/gc_stack_1.o
clang version 19.0.0git (https:/github.com/llvm/llvm-project 0a8cd1ed1f4f35905df318015b0dbcb69d81d7c2)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/martin/code/emsdk/upstream/bin
 (in-process)
 "/home/martin/code/emsdk/upstream/bin/clang-19" -cc1 -triple wasm32-unknown-emscripten -emit-obj -mrelax-all -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gc_stack.c -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/martin/Documents/sm_gauss_nat -v -fcoverage-compilation-dir=/home/martin/Documents/sm_gauss_nat -resource-dir /home/martin/code/emsdk/upstream/lib/clang/19 -D EMSCRIPTEN -I ./ -isysroot /home/martin/code/emsdk/upstream/emscripten/cache/sysroot -internal-isystem /home/martin/code/emsdk/upstream/lib/clang/19/include -internal-isystem /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten -internal-isystem /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include -O0 -Werror=implicit-function-declaration -Wno-everything -w -ferror-limit 19 -fvisibility=default -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fignore-exceptions -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_ald21kk8/gc_stack_1.o -x c gc_stack.c
clang -cc1 version 19.0.0git based upon LLVM 19.0.0git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
 .
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/fakesdl
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/compat
 /home/martin/code/emsdk/upstream/lib/clang/19/include
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include
End of search list.
 /home/martin/code/emsdk/upstream/bin/clang -target wasm32-unknown-emscripten -fignore-exceptions -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/home/martin/code/emsdk/upstream/emscripten/cache/sysroot -DEMSCRIPTEN -Werror=implicit-function-declaration -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -v -O0 -w -Wno-everything -I./ CertiCoq.Benchmarks.tests.sm_gauss_nat.c -c -o /tmp/emscripten_temp_ald21kk8/CertiCoq.Benchmarks.tests.sm_gauss_nat_2.o
clang version 19.0.0git (https:/github.com/llvm/llvm-project 0a8cd1ed1f4f35905df318015b0dbcb69d81d7c2)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/martin/code/emsdk/upstream/bin
 (in-process)
 "/home/martin/code/emsdk/upstream/bin/clang-19" -cc1 -triple wasm32-unknown-emscripten -emit-obj -mrelax-all -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name CertiCoq.Benchmarks.tests.sm_gauss_nat.c -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/martin/Documents/sm_gauss_nat -v -fcoverage-compilation-dir=/home/martin/Documents/sm_gauss_nat -resource-dir /home/martin/code/emsdk/upstream/lib/clang/19 -D EMSCRIPTEN -I ./ -isysroot /home/martin/code/emsdk/upstream/emscripten/cache/sysroot -internal-isystem /home/martin/code/emsdk/upstream/lib/clang/19/include -internal-isystem /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten -internal-isystem /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include -O0 -Werror=implicit-function-declaration -Wno-everything -w -ferror-limit 19 -fvisibility=default -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fignore-exceptions -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_ald21kk8/CertiCoq.Benchmarks.tests.sm_gauss_nat_2.o -x c CertiCoq.Benchmarks.tests.sm_gauss_nat.c
clang -cc1 version 19.0.0git based upon LLVM 19.0.0git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
 .
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/fakesdl
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/compat
 /home/martin/code/emsdk/upstream/lib/clang/19/include
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include
End of search list.
 /home/martin/code/emsdk/upstream/bin/clang -target wasm32-unknown-emscripten -fignore-exceptions -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/home/martin/code/emsdk/upstream/emscripten/cache/sysroot -DEMSCRIPTEN -Werror=implicit-function-declaration -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -v -O0 -w -Wno-everything -I./ glue_sm_gauss_nat.c -c -o /tmp/emscripten_temp_ald21kk8/glue_sm_gauss_nat_3.o
clang version 19.0.0git (https:/github.com/llvm/llvm-project 0a8cd1ed1f4f35905df318015b0dbcb69d81d7c2)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/martin/code/emsdk/upstream/bin
 (in-process)
 "/home/martin/code/emsdk/upstream/bin/clang-19" -cc1 -triple wasm32-unknown-emscripten -emit-obj -mrelax-all -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name glue_sm_gauss_nat.c -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/martin/Documents/sm_gauss_nat -v -fcoverage-compilation-dir=/home/martin/Documents/sm_gauss_nat -resource-dir /home/martin/code/emsdk/upstream/lib/clang/19 -D EMSCRIPTEN -I ./ -isysroot /home/martin/code/emsdk/upstream/emscripten/cache/sysroot -internal-isystem /home/martin/code/emsdk/upstream/lib/clang/19/include -internal-isystem /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten -internal-isystem /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include -O0 -Werror=implicit-function-declaration -Wno-everything -w -ferror-limit 19 -fvisibility=default -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fignore-exceptions -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_ald21kk8/glue_sm_gauss_nat_3.o -x c glue_sm_gauss_nat.c
clang -cc1 version 19.0.0git based upon LLVM 19.0.0git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
 .
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/fakesdl
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include/compat
 /home/martin/code/emsdk/upstream/lib/clang/19/include
 /home/martin/code/emsdk/upstream/emscripten/cache/sysroot/include
End of search list.
 /home/martin/code/emsdk/upstream/bin/clang --version
cache:INFO: generating system asset: symbol_lists/ddda1e3705a2cc29dceb5e6eb4f1cd9a3a4e8663.json... (this will be cached in "/home/martin/code/emsdk/upstream/emscripten/cache/symbol_lists/ddda1e3705a2cc29dceb5e6eb4f1cd9a3a4e8663.json" for subsequent builds)
 /home/martin/code/emsdk/node/16.20.0_64bit/bin/node /home/martin/code/emsdk/upstream/emscripten/src/compiler.mjs /tmp/tmpsoi5da8f.json --symbols-only
cache:INFO:  - ok
 /home/martin/code/emsdk/upstream/bin/wasm-ld -o sm_gauss_nat-opt_O0.wasm -L/home/martin/code/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten /tmp/emscripten_temp_ald21kk8/sm_gauss_nat_main_wasm_0.o /tmp/emscripten_temp_ald21kk8/gc_stack_1.o /tmp/emscripten_temp_ald21kk8/CertiCoq.Benchmarks.tests.sm_gauss_nat_2.o /tmp/emscripten_temp_ald21kk8/glue_sm_gauss_nat_3.o -lGL-getprocaddr -lal -lhtml5 -lstubs-debug -lnoexit -lc-debug -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-debug-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmpiyvbk_s_libemscripten_js_symbols.so --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=__get_temp_ret --export=__set_temp_ret --export=__wasm_call_ctors --export=_emscripten_stack_restore --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=100000 --max-memory=2147483648 --initial-heap=16777216 --no-entry --stack-first --table-base=1
 /home/martin/code/emsdk/upstream/bin/llvm-objcopy sm_gauss_nat-opt_O0.wasm sm_gauss_nat-opt_O0.wasm --remove-section=.debug* --remove-section=producers
 /home/martin/code/emsdk/upstream/bin/wasm-emscripten-finalize -g --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers sm_gauss_nat-opt_O0.wasm -o sm_gauss_nat-opt_O0.wasm --detect-features
 /home/martin/code/emsdk/node/16.20.0_64bit/bin/node /home/martin/code/emsdk/upstream/emscripten/src/compiler.mjs /tmp/tmprp74a2fd.json
@kripken
Copy link
Member

kripken commented Apr 29, 2024

increasing the stack size seems to cause a segmentation fault for me when trying to run with node.

That should fix it, so that segfault needs to be looked into. Do you mean a segfault in node itself, or in the compiled code? What is the output you see?

@mkarup
Copy link
Author

mkarup commented May 16, 2024

Sorry for the late, late reply. Adding -O1 and specifying a large enough stack size and initial memory produces the correct result, so that's a mistake on my part.

As far as I can tell, the segfault arises from specifying a stack size that is too large when invoking node itself with --stack-size=X, e.g. with X=11000000 on my machine, but maybe that is intended/ the expected behavior with such a large size? (but this is something with node, not emscripten)

With no optimization flags, I can also increase the stack size and initial memory to the point where I don't get the stack overflow/ memory out of bounds errors, but the behavior differs, similar to this issue, so I will continue in that other issue.
For what it's worth, I tried compiling with both the undefined behavior sanitizer and the address sanitizer, but the binary that is produced with sanitizers has functions with too many locals (I also tried with the minimal runtime), and adding -sASSERTIONS=2 and -sSAFE_HEAP doesn't tell me anything.

@mkarup mkarup closed this as completed May 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants