Skip to content

Unable to add _emscripten_thread_exit_joinable to EXPORTED_FUNCTIONS #22108

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

Closed
allsey87 opened this issue Jun 18, 2024 · 13 comments · Fixed by #22110
Closed

Unable to add _emscripten_thread_exit_joinable to EXPORTED_FUNCTIONS #22108

allsey87 opened this issue Jun 18, 2024 · 13 comments · Fixed by #22110

Comments

@allsey87
Copy link

allsey87 commented Jun 18, 2024

When building with both -pthread and -sRELOCATABLE, I get an error saying that _emscripten_thread_exit_joinable needs to be added to EXPORTED_FUNCTIONS. However, while adding EXPORTED_FUNCTIONS=__emscripten_thread_exit_joinable shows that --export=_emscripten_thread_exit_joinable is now passed to wasm-ld, I get the exact same error.

This issue is related to #21844, but I would like to focus here on why EXPORTED_FUNCTIONS is not working.

Version of emscripten/emsdk:

root@2d7bfb9259d9:/src# emcc -v
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
InstalledDir: /emsdk/upstream/bin

Failing command line in full:

emcc -v -pthread -sRELOCATABLE -sEXPORTED_FUNCTIONS=_main,__emscripten_thread_exit_joinable test.c

Test.c source

root@2d7bfb9259d9:/src# cat test.c 
int main() {
    return 0;
}

Full link command and output with -v appended:

root@2d7bfb9259d9:/src# emcc -v -pthread -sRELOCATABLE -sEXPORTED_FUNCTIONS=_main,__emscripten_thread_exit_joinable test.c 
 /emsdk/upstream/bin/clang -target wasm32-unknown-emscripten -fignore-exceptions -fPIC -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/emsdk/upstream/emscripten/cache/sysroot -D__EMSCRIPTEN_SHARED_MEMORY__=1 -DEMSCRIPTEN -Werror=implicit-function-declaration -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -v -pthread -matomics -mbulk-memory test.c -c -o /tmp/emscripten_temp__0hwmhis/test_0.o
clang version 19.0.0git (https:/github.com/llvm/llvm-project 7cfffe74eeb68fbb3fb9706ac7071f8caeeb6520)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /emsdk/upstream/bin
 (in-process)
 "/emsdk/upstream/bin/clang-19" -cc1 -triple wasm32-unknown-emscripten -emit-obj -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name test.c -mrelocation-model pic -pic-level 2 -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-feature +mutable-globals -target-cpu generic -target-feature +atomics -target-feature +bulk-memory -debugger-tuning=gdb -fdebug-compilation-dir=/src -v -fcoverage-compilation-dir=/src -resource-dir /emsdk/upstream/lib/clang/19 -D __EMSCRIPTEN_SHARED_MEMORY__=1 -D EMSCRIPTEN -isysroot /emsdk/upstream/emscripten/cache/sysroot -internal-isystem /emsdk/upstream/lib/clang/19/include -internal-isystem /emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten -internal-isystem /emsdk/upstream/emscripten/cache/sysroot/include -Werror=implicit-function-declaration -ferror-limit 19 -fvisibility=default -pthread -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__0hwmhis/test_0.o -x c test.c
clang -cc1 version 19.0.0git based upon LLVM 19.0.0git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
 /emsdk/upstream/emscripten/cache/sysroot/include/fakesdl
 /emsdk/upstream/emscripten/cache/sysroot/include/compat
 /emsdk/upstream/lib/clang/19/include
 /emsdk/upstream/emscripten/cache/sysroot/include
End of search list.
 /emsdk/upstream/bin/clang --version
 /emsdk/upstream/bin/wasm-ld -o a.out.wasm -L/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/pic /tmp/emscripten_temp__0hwmhis/test_0.o /emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/pic/crtbegin.o -lGL-mt-getprocaddr -lal -lhtml5 -lbulkmemory -lstubs-debug -lnoexit -lc-mt-debug -ldlmalloc-mt -lcompiler_rt-mt -lc++-mt-noexcept -lc++abi-debug-mt-noexcept -lsockets-mt -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmp7cxrjadnlibemscripten_js_symbols.so --import-memory --shared-memory --strip-debug --export=_emscripten_thread_exit_joinable --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_get_base --export=emscripten_stack_get_current --export=emscripten_stack_set_limits --export=_emscripten_stack_alloc --export=_emscripten_thread_free_data --export=_emscripten_thread_crashed --export=emscripten_main_runtime_thread_id --export=emscripten_main_thread_process_queued_calls --export=_emscripten_run_on_main_thread_js --export=__get_temp_ret --export=__set_temp_ret --export=__wasm_call_ctors --export=_emscripten_tls_init --export=_emscripten_thread_init --export=setThrew --export=_emscripten_stack_restore --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=__wasm_apply_data_relocs --export-if-defined=fflush --experimental-pic --unresolved-symbols=import-dynamic -pie --no-export-dynamic -z stack-size=65536 --no-growable-memory --initial-memory=16777216 --no-entry --stack-first
 /emsdk/upstream/bin/llvm-objcopy a.out.wasm a.out.wasm --remove-section=.debug* --remove-section=producers
 /emsdk/upstream/bin/wasm-emscripten-finalize --dyncalls-i64 --pass-arg=legalize-js-interface-export-originals --pass-arg=legalize-js-interface-exported-helpers a.out.wasm -o a.out.wasm --detect-features
 /emsdk/node/18.20.3_64bit/bin/node /emsdk/upstream/emscripten/src/compiler.mjs /tmp/tmphvry3t52.json
error: undefined symbol: _emscripten_thread_exit_joinable (referenced by root reference (e.g. compiled C/C++ code))
warning: To disable errors for undefined symbols use `-sERROR_ON_UNDEFINED_SYMBOLS=0`
warning: __emscripten_thread_exit_joinable may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
Error: Aborting compilation due to previous errors
emcc: error: '/emsdk/node/18.20.3_64bit/bin/node /emsdk/upstream/emscripten/src/compiler.mjs /tmp/tmphvry3t52.json' failed (returned 1)
@sbc100
Copy link
Collaborator

sbc100 commented Jun 18, 2024

Can I ask why are you trying to build with -sRELOCATABLE? Obviously we should fix this, but using that flag directly not common/recommended.

@sbc100
Copy link
Collaborator

sbc100 commented Jun 18, 2024

The reason that _emscripten_thread_exit_joinable is not available is that that symbol is only defined when -sMAIN_MODULE is used:

#if MAIN_MODULE
_emscripten_thread_exit_joinable: (thread) => {

Unfortunetly at the callsite we protect that call with -DEMSCRIPTEN_DYNAMIC_LINKING which I believe is set whenever -sRELOCTABLE is used.. so there is a mismatch there:

#ifdef EMSCRIPTEN_DYNAMIC_LINKING
// When dynamic linking is enabled we need to keep track of zombie threads
_emscripten_thread_exit_joinable(self);
#endif

sbc100 added a commit to sbc100/emscripten that referenced this issue Jun 18, 2024
@allsey87
Copy link
Author

Can I ask why are you trying to build with -sRELOCATABLE? Obviously we should fix this, but using that flag directly not common/recommended.

I am probably a bit confused here, but I am trying to compile a set of static libraries that will be linked into either the main module or the side module. Now these libraries are built via Autoconf and Automake so the build process also includes compiling small test programs to see what features emcc has.

Initially I was just using -fPIC since I thought that neither -sMAIN_MODULE or -sSIDE_MODULE made sense here, but just using -fPIC alone is not enough to get PIC variants of system libraries from the cache. In order to get the PIC variants, -sRELOCATABLE has to be set (or set indirectly via -sMAIN_MODULE or -sSIDE_MODULE in emcc) to get the correct cache path.

Since I am compiling static libraries, I guess the version of the cache in use doesn't really matter since the static library will never actually be linked against anything in there, but I thought for the configure script compiler tests it would be more correct for those tests to use the system libraries coming from the correct cache path.

@sbc100
Copy link
Collaborator

sbc100 commented Jun 19, 2024

If you are building static libraries that you don't need -fPIC or MAIN_MODULE. For autoconf and automake and would recommend disabling dynamic linking completely using --disable-shared.

@allsey87
Copy link
Author

Huh, I thought the code would still need to be compiled with -fPIC if it is going to be linked into a relocatable module at some point...

@sbc100
Copy link
Collaborator

sbc100 commented Jun 19, 2024

Sure, yes, if you the final output is a MAIN_MODULE or a SIDE_MODULE than yes you would want to build with -fPIC. Is your final output of those?

@sbc100
Copy link
Collaborator

sbc100 commented Jun 19, 2024

In any case #22110 should fix this particular bug. In the long run I'm still hoping we can remove -sRELOCATBLE as a link flag since we don't test that mode fully, and I'm not sure what its usefulness is these days.

@allsey87
Copy link
Author

allsey87 commented Jun 19, 2024

Sure, yes, if you the final output is a MAIN_MODULE or a SIDE_MODULE than yes you would want to build with -fPIC. Is your final output of those?

Yes, the final output will be either a MAIN_MODULE or SIDE_MODULE, the reason for adding -sRELOCATBLE is because I want the configure tests to link against the -fPIC variants of the system libraries since those are the only ones available when using emscripten_cache(flags = ["--pic"]).

@sbc100
Copy link
Collaborator

sbc100 commented Jun 19, 2024

In that case I would recommend using -sMAIN_MODULE=2 rather then -sRELOCTABLE

@sbc100
Copy link
Collaborator

sbc100 commented Jun 19, 2024

Sure, yes, if you the final output is a MAIN_MODULE or a SIDE_MODULE than yes you would want to build with -fPIC. Is your final output of those?

Yes, the final output will be either a MAIN_MODULE or SIDE_MODULE, the reason for adding -sRELOCATBLE is because I want the configure tests to link against the -fPIC variants of the system libraries since those are the only ones available when using emscripten_cache(flags = ["--pic"]).

Can't you setup the cache to contains both types of libraries? What if you have a statically linked binary and a dynamically linked binary in the same project?

@allsey87
Copy link
Author

Yeah, I was thinking that. Once I get some initial feedback on the direction of that PR, I will investigate calling embuilder multiple times with the different configurations.

@allsey87
Copy link
Author

In that case I would recommend using -sMAIN_MODULE=2 rather then -sRELOCTABLE

This is a decent workaround, but it seems incorrect that by default, if I compile code with -fPIC, it will link against non--fPIC system libraries. Perhaps the cache should be checking these flags directly instead of relying on the higher level Emscripten arguments like -sRELOCATABLE?

@sbc100
Copy link
Collaborator

sbc100 commented Jun 20, 2024

I'm proposing that we drop -sRELOCATABLE completely... unless you can think of a good use case for it.

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

Successfully merging a pull request may close this issue.

2 participants