-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Emscripten crashes when using thread_local
variables wihtout -pthread
and -flto
enabled
#22880
Comments
I don't see an issue in a trivial attempt to reproduce this: thread_local int x = 10;
int main(int argc, char **argv) {
x += argc;
return x;
}
@yosoymin Can you create a standalone testcase that shows the issue? |
I also tried with a more complex example that used
Here you can see that x is incremented from 0, by 4 each time |
While reducing the code as much as possible I noticed that the only way to reproduce the error was to link with an external library. After that, I figured out the problem. I was setting |
Doing that (compiling with -pthread and linking without) should still work and produce perfectly valid programs that just run without any threads. If that doesn't work that would be considered a bug. |
This small project reproduces the error. I have pointed out the key lines that cause this error to be reproduced, with any of them that are modified, the error disappears. In my complete project I have not been able to get the |
Finally, I found the problem in my project: the library libwebp, which enables pthreads by default. |
So presumably we should be able to make the simple program in #22880 (comment) crash? I can't seem to make it crash with or without using |
I updated my test program so that it asserts if the
You can see the TLS variable doesn't live in the stack range (it lives at 0x20000 and the stack 0x0-0x10000) |
I've only been able to reproduce the error if I link with an static library that is compiled with |
I've simplified the code reproducing the error. No CMake, Ninja, or static library is needed. And I've uploaded to this Github repo: https://github.com/yosoymin/EmscriptenThreadLocalCrash |
Thanks for the simpler repro @yosoymin. BTW do you know you can run/test this kind of stuff under node. My simplified setup:
|
I was able to narrow the test down more. Still fails even with
|
…shared memory TLS-relative relocation always need to be relative the TLS section since they get added to `__tls_base` at runtime. Without this change the tls base address was effectively being added to the final value twice in this case. This only effects code the is built with `-pthread` but linked without shared memory (i.e. without threads). Fixes: emscripten-core/emscripten#22880
I tracked this down to a linker bug! Fix is here: llvm/llvm-project#116136 |
…shared memory TLS-relative relocation always need to be relative the TLS section since they get added to `__tls_base` at runtime. Without this change the tls base address was effectively being added to the final value twice in this case. This only effects code the is built with `-pthread` but linked without shared memory (i.e. without threads). Fixes: emscripten-core/emscripten#22880
…shared memory TLS-relative relocation always need to be relative the TLS section since they get added to `__tls_base` at runtime. Without this change the tls base address was effectively being added to the final value twice in this case. This only effects code the is built with `-pthread` but linked without shared memory (i.e. without threads). Fixes: emscripten-core/emscripten#22880
…shared memory TLS-relative relocation always need to be relative the TLS section since they get added to `__tls_base` at runtime. Without this change the tls base address was effectively being added to the final value twice in this case. This only effects code the is built with `-pthread` but linked without shared memory (i.e. without threads). Fixes: emscripten-core/emscripten#22880
…shared memory TLS-relative relocation always need to be relative the TLS section since they get added to `__tls_base` at runtime. Without this change the tls base address was effectively being added to the final value twice in this case. This only effects code the is built with `-pthread` but linked without shared memory (i.e. without threads). Fixes: emscripten-core/emscripten#22880
…shared memory (#116136) TLS-relative relocations always need to be relative the TLS section since they get added to `__tls_base` at runtime. Without this change the tls base address was effectively being added to the final value twice in this case. This only effects code the is built with `-pthread` but linked without shared memory (i.e. without threads). Fixes: emscripten-core/emscripten#22880
…shared memory (llvm#116136) TLS-relative relocations always need to be relative the TLS section since they get added to `__tls_base` at runtime. Without this change the tls base address was effectively being added to the final value twice in this case. This only effects code the is built with `-pthread` but linked without shared memory (i.e. without threads). Fixes: emscripten-core/emscripten#22880
Hello, I'm having problems with thread_local variables when the build is performed without
-pthread
and with-flto
enabled.I've noticed that when the runtime arrives at a
thread_local
variable, there is a crash. It seems like the variable was declared as a temporal variable (if inside a function scope) instead of a static variable. For global variables, it seems like the initialization value is not guaranteed to be 0.With
-pthread
compile and link flag, the problem goes away, but I need a specific build without pthreads to support environments that don't supportSharedArrayBuffer
due to CORS problems.The same thing happens if we remove the
-flto
compile and link flag, but we want to have the smallest possible binary.As a workaround, I've defined a custom symbol to mark
thread_local
variables in our code. Something like this:But for other third-party libraries, or even Emscripten itself, this is not possible and the workaround is more hacky. In particular, Emscripten uses
thread_local
variables in<emscripten/val.h>
and<emscripten/bind.h>
header files. If you try to use coroutines, then you will have a crash inside the<emscripten/val.h>
file:For this specific case, this is the workaround that is working for me. Instead of including directly the header
<emscripten/val.h>
I have to include a custom file called"emscriptenVal.h"
with the next content:Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.68 (ceee49d)
clang version 20.0.0git (https:/github.com/llvm/llvm-project 5cc64bf60bc04b9315de3c679eb753de4d554a8a)
Target: wasm32-unknown-emscripten
Thread model: posix
Full link command and output with
-v
appended:"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/upstream/bin\clang.exe" --version
"D:\Code\Nebula\Nebula-Viewer\Code\Libs\SDKs\emsdk\upstream\emscripten\tools\file_packager.bat" D:\Code\Nebula\Nebula-Viewer_Output\html\wasm\GoldenViewerNoThreads.data --from-emcc --embed D:/Code/Nebula/Nebula-Viewer/Code/Src/GoldenViewer/../../../_Output/desktop/chrome.gtpak@/chrome.gtpak D:/Code/Nebula/Nebula-Viewer/Code/Src/GoldenViewer/../../../_Output/scripts/chrome_scripts.gtpak@/chrome_scripts.gtpak --no-node --obj-output=C:\Users\yosoy\AppData\Local\Temp\emscripten_temp_dylnnf24\embedded_files.o
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/upstream/bin\wasm-ld.exe" -o D:\Code\Nebula\Nebula-Viewer_Output\html\wasm\GoldenViewerNoThreads.wasm -lembind-rtti Src/GoldenViewer/CMakeFiles/GoldenViewer.dir/Distribution/src/GenericEntryPoint.cpp.o Src/GoldenViewerLib/Distribution/libGoldenViewerLib.a Libs/GameEngine/Distribution/libGameEngine.a Libs/Aurora/Code/Libs/bullet/Distribution/libbullet.a clip_external-prefix/src/clip_external-build/Distribution/libclip.a Libs/Aurora/Code/Src/auVideo/Distribution/libauVideo.a Libs/Aurora/Code/Libs/freetype/Distribution/libfreetype.a ktx_read_external-prefix/src/ktx_read_external-build/Distribution/libktx_read.a Libs/Aurora/Code/Libs/imgui/Distribution/libimgui.a Libs/Aurora/Code/Src/auGeom/Distribution/libauGeom.a Libs/Aurora/Code/Src/auImage/Distribution/libauImage.a png_static_external-prefix/src/png_static_external-build/Distribution/libpng16.a webp_external-prefix/src/webp_external-build/Distribution/libwebp.a webp_external-prefix/src/webp_external-build/Distribution/libwebpdecoder.a webp_external-prefix/src/webp_external-build/Distribution/libsharpyuv.a avif_external-prefix/src/avif_external-build/Distribution/libavif.a aom_external-prefix/src/aom_external-build/Distribution/libaom.a yuv_external-prefix/src/yuv_external-build/Distribution/libyuv.a Libs/Aurora/Code/Src/auSound/Distribution/libauSound.a Libs/Aurora/Code/Libs/libvorbis-1.3.7/Distribution/liblibvorbis-1.3.7.a Libs/Aurora/Code/Src/auNetwork/Distribution/libauNetwork.a Libs/Aurora/Code/Src/auCore/Distribution/libauCore.a fmt_external-prefix/src/fmt_external-build/Distribution/libfmt.a zlibstatic_external-prefix/src/zlibstatic_external-build/Distribution/libz.a Libs/Aurora/Code/Libs/yajl/Distribution/libyajl.a Libs/Aurora/Code/Libs/lua/Distribution/liblua_static.a -LD:\Code\Nebula\Nebula-Viewer\Code\Libs\SDKs\emsdk\upstream\emscripten\cache\sysroot\lib\wasm32-emscripten\lto -lfetch C:\Users\yosoy\AppData\Local\Temp\emscripten_temp_dylnnf24\embedded_files.o D:\Code\Nebula\Nebula-Viewer\Code\Libs\SDKs\emsdk\upstream\emscripten\cache\sysroot\lib\wasm32-emscripten\lto\libSDL2.a -lGL-webgl2-getprocaddr -lal -lhtml5 -lc_optz -lbulkmemory -lstubs -lc -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr C:\Users\yosoy\AppData\Local\Temp\tmpn2i23s1dlibemscripten_js_symbols.so --strip-debug --export=_emscripten_stack_alloc --export=__getTypeName --export=__funcs_on_exit --export=__wasm_call_ctors --export=emscripten_stack_get_current --export=_emscripten_stack_restore --export=malloc --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=131072 --max-memory=1073741824 --initial-memory=67108864 --no-entry --table-base=1 --global-base=1024
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/upstream/bin\llvm-objcopy.exe" D:\Code\Nebula\Nebula-Viewer_Output\html\wasm\GoldenViewerNoThreads.wasm D:\Code\Nebula\Nebula-Viewer_Output\html\wasm\GoldenViewerNoThreads.wasm --remove-section=.debug* --remove-section=producers
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/node/20.18.0_64bit/bin/node.exe" D:\Code\Nebula\Nebula-Viewer\Code\Libs\SDKs\emsdk\upstream\emscripten\src\compiler.mjs C:\Users\yosoy\AppData\Local\Temp\tmp5blpl22o.json
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/node/20.18.0_64bit/bin/node.exe" D:\Code\Nebula\Nebula-Viewer\Code\Libs\SDKs\emsdk\upstream\emscripten\src\compiler.mjs C:\Users\yosoy\AppData\Local\Temp\tmp9w4a_2d5.json
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/node/20.18.0_64bit/bin/node.exe" C:\Users\yosoy\AppData\Local\Temp\emscripten_temp_dylnnf24\tsgen.js
"D:\Code\Nebula\Nebula-Viewer\Code\Libs\SDKs\emsdk\upstream\emscripten\node_modules.bin\tsc.cmd" --outFile C:\Users\yosoy\AppData\Local\Temp\emscripten_temp_dylnnf24\jsdoc.d.ts --declaration --emitDeclarationOnly --allowJs C:\Users\yosoy\AppData\Local\Temp\emscripten_temp_dylnnf24\jsdoc.js
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/upstream\bin\wasm-opt" --strip-target-features --post-emscripten -Oz --low-memory-unused --zero-filled-memory --pass-arg=directize-initial-contents-immutable --no-stack-ir D:\Code\Nebula\Nebula-Viewer_Output\html\wasm\GoldenViewerNoThreads.wasm -o D:\Code\Nebula\Nebula-Viewer_Output\html\wasm\GoldenViewerNoThreads.wasm --mvp-features --enable-threads --enable-bulk-memory --enable-multivalue --enable-mutable-globals --enable-reference-types --enable-sign-ext
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/node/20.18.0_64bit/bin/node.exe" D:\Code\Nebula\Nebula-Viewer\Code\Libs\SDKs\emsdk\upstream\emscripten\tools\acorn-optimizer.mjs C:\Users\yosoy\AppData\Local\Temp\emscripten_temp_dylnnf24\GoldenViewerNoThreads.js AJSDCE --minify-whitespace -o C:\Users\yosoy\AppData\Local\Temp\emscripten_temp_dylnnf24\GoldenViewerNoThreads.jso1.js
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/node/20.18.0_64bit/bin/node.exe" D:\Code\Nebula\Nebula-Viewer\Code\Libs\SDKs\emsdk\upstream\emscripten\tools\acorn-optimizer.mjs C:\Users\yosoy\AppData\Local\Temp\emcc_acorn_info_6m5d1w8o.js emitDCEGraph --no-print
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/upstream\bin\wasm-metadce" --graph-file=C:\Users\yosoy\AppData\Local\Temp\emcc_dce_graph_vod_qa8s.json D:\Code\Nebula\Nebula-Viewer_Output\html\wasm\GoldenViewerNoThreads.wasm -o D:\Code\Nebula\Nebula-Viewer_Output\html\wasm\GoldenViewerNoThreads.wasm --mvp-features --enable-threads --enable-bulk-memory --enable-multivalue --enable-mutable-globals --enable-reference-types --enable-sign-ext
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/node/20.18.0_64bit/bin/node.exe" D:\Code\Nebula\Nebula-Viewer\Code\Libs\SDKs\emsdk\upstream\emscripten\tools\acorn-optimizer.mjs C:\Users\yosoy\AppData\Local\Temp\emcc_acorn_info_ilu11rgi.js applyDCEGraphRemovals --minify-whitespace -o C:\Users\yosoy\AppData\Local\Temp\emscripten_temp_dylnnf24\GoldenViewerNoThreads.jso2.js
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/node/20.18.0_64bit/bin/node.exe" D:\Code\Nebula\Nebula-Viewer\Code\Libs\SDKs\emsdk\upstream\emscripten\tools\acorn-optimizer.mjs C:\Users\yosoy\AppData\Local\Temp\emscripten_temp_dylnnf24\GoldenViewerNoThreads.jso2.js AJSDCE --minify-whitespace -o C:\Users\yosoy\AppData\Local\Temp\emscripten_temp_dylnnf24\GoldenViewerNoThreads.jso3.js
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/upstream\bin\wasm-opt" --minify-imports-and-exports-and-modules --optimize-level=2 --shrink-level=2 --optimize-stack-ir D:\Code\Nebula\Nebula-Viewer_Output\html\wasm\GoldenViewerNoThreads.wasm -o D:\Code\Nebula\Nebula-Viewer_Output\html\wasm\GoldenViewerNoThreads.wasm --mvp-features --enable-threads --enable-bulk-memory --enable-multivalue --enable-mutable-globals --enable-reference-types --enable-sign-ext
"D:/Code/Nebula/Nebula-Viewer/Code/Libs/SDKs/emsdk/node/20.18.0_64bit/bin/node.exe" D:\Code\Nebula\Nebula-Viewer\Code\Libs\SDKs\emsdk\upstream\emscripten\tools\acorn-optimizer.mjs C:\Users\yosoy\AppData\Local\Temp\emcc_acorn_info_y_vvsusf.js applyImportAndExportNameChanges --minify-whitespace -o C:\Users\yosoy\AppData\Local\Temp\emscripten_temp_dylnnf24\GoldenViewerNoThreads.jso4.js
The text was updated successfully, but these errors were encountered: