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

table index out of bounds when create a thread from within dynamic library (the thread function is defined in dynamic library) #19425

Open
0-0alephant opened this issue May 23, 2023 · 6 comments

Comments

@0-0alephant
Copy link

0-0alephant commented May 23, 2023

Please include the following in your bug report:

Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.34 (57b21b8)
clang version 17.0.0 (https://github.com/llvm/llvm-project a031f72187ce495b9faa4ccf99b1e901a3872f4b)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: D:\emsdk\upstream\bin

Failing command line in full:
worker.js onmessage() captured an uncaught exception: RuntimeError: table index is out of bounds

i'm trying to spawn a function defined in dynamical library.but I always get table index outof bounds, what are the alternatives? or is it simply impossible?

the defined function is not called by any other threads but this one, and the thread is immediately joined, the function is doing harmless things none other than calculations and printing stuff, there's no harmful api calls at all, this should be possible in the web sandbox since it can set the PC to the corresponding symbol start. but it seems the access is restricted.

@sbc100
Copy link
Collaborator

sbc100 commented May 23, 2023

This should certainly work but you could have found a bug in our (experimental) support for dynamic linking + threading. Is there some way would could include a full sample? If not, perhaps you could share the full link command used for your main and your side modules?

@0-0alephant
Copy link
Author

0-0alephant commented May 24, 2023

This should certainly work but you could have found a bug in our (experimental) support for dynamic linking + threading. Is there some way would could include a full sample? If not, perhaps you could share the full link command used for your main and your side modules?

Do you mean by a minimum sample to reproduce this?
minimum-example (2).zip
(file updated and removed some unnecessary code)

run make, only tested under windows with chrome as of now.

after running make, server page will be at localhost:8000/a.html

@0-0alephant
Copy link
Author

0-0alephant commented May 24, 2023

in the example zip , if thread_func is defined in main.cc, everything works fine, but if the thread_func is defined in the sidemodule, then it will result in the following table index out of bounds
Screenshot 2023-05-24 084631

@0-0alephant
Copy link
Author

I realized that the minimum example code size is so small, after removing some visual noice, putting it here still got some readability

main module

int main() {
  void *p = dlopen("dynlib.wasm", RTLD_LAZY);
  dyn_func_p test_ptr = (dyn_func_p)dlsym(p, "dyn_func");
  test_ptr(&pthread); 
}

side module dynlib.wasm

void *thread_func(void *arg) { //<--- harmless thread function in dynlib.wasm except born in an unnatual place.
  std::cout << "Hello from thread" << std::endl;
  pthread_exit(NULL);
}

extern "C" {
void dyn_func(pthread_t *pthread) { // <--- called by main
  pthread_create(pthread, NULL, thread_func, NULL);// Error : table index out of bounds
  pthread_join(*pthread, NULL); 
}
}

@ryanabx
Copy link

ryanabx commented Sep 22, 2023

The Godot Engine devs are waiting on a fix for this to get web platform support for GDExtension.

See: godotengine/godot#79578

@Faless
Copy link
Contributor

Faless commented Oct 1, 2023

The Godot Engine devs are waiting on a fix for this to get web platform support for GDExtension.

See: godotengine/godot#79578

After some more in-depth testing, it seems that our issue was a result of some functions not being properly exposed (we need to use -fvisibility=hidden to avoid having 12k+ symbols, which is above the browsers hard limit of 10k).

Interestingly though, we do start thread functions defined in the side module, and yet they do seem to work now 👀 .

The main difference I see with the reproduction project above is that we use RTLD_NOW instead of RTLD_LAZY (using the Module["dynamicLibraries"] property so the libraries are loaded during init)

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

4 participants