wasm-pack
wasm-pack copied to clipboard
Bug in the browser when using wasm-pack for a multithreaded Rust function
🐛 Bug description
Hello, when trying to use wasm-pack to use in a web front-end (nextjs) a multi-threaded Rust function, I keep getting this kind of error in the browser :
6fd63e3ac1df08b3.wasm:0x16b97 Uncaught RuntimeError: unreachable
at __rust_start_panic (6fd63e3ac1df08b3.wasm:0x16b97)
at rust_panic (6fd63e3ac1df08b3.wasm:0x169ea)
at std::panicking::rust_panic_with_hook::h2459a4820b3cee55 (6fd63e3ac1df08b3.wasm:0x13a5e)
at std::panicking::begin_panic_handler::{{closure}}::h5a2e2a0bf8acf274 (6fd63e3ac1df08b3.wasm:0x147d0)
at std::sys_common::backtrace::__rust_end_short_backtrace::h3cabe7515cf241e1 (6fd63e3ac1df08b3.wasm:0x16b2f)
at rust_begin_unwind (6fd63e3ac1df08b3.wasm:0x15960)
at core::panicking::panic_fmt::h52afce83e8bac1f5 (6fd63e3ac1df08b3.wasm:0x160ce)
at core::result::unwrap_failed::h5fbbb6142ec016b2 (6fd63e3ac1df08b3.wasm:0x153a1)
at std::thread::spawn::h4c3279e58b453d9a (6fd63e3ac1df08b3.wasm:0x15e5a)
at do_compute_dlog (6fd63e3ac1df08b3.wasm:0x4474)
at Module.do_compute_dlog (webpack-internal:///(:3000/app-pages-browser)/../circuits/exponential_elgamal/babygiant/pkg/index_bg.js:102:22)
at calculate (webpack-internal:///(:3000/app-pages-browser)/./lib/Babygiant.tsx:27:29)
at HTMLUnknownElement.callCallback (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:19443:14)
at Object.invokeGuardedCallbackImpl (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:19492:16)
at invokeGuardedCallback (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:19567:29)
at invokeGuardedCallbackAndCatchFirstError (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:19581:25)
at executeDispatch (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30621:3)
at processDispatchQueueItemsInOrder (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30653:7)
at processDispatchQueue (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30666:5)
at dispatchEventsForPlugins (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30677:3)
at eval (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30867:12)
at batchedUpdates$1 (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:23747:12)
at batchedUpdates (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:27583:12)
at dispatchEventForPluginEventSystem (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30866:3)
at dispatchEvent (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:28639:5)
at dispatchDiscreteEvent (webpack-internal:///(:3000/app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:28610:5)
This only happens in the browser : my Rust tests are passing in my lib.rs file which uses the same function (with #[wasm_bindgen]
decorator) and same inputs as in the front-end. Could any of you help me with this issue please? :pray::skin-tone-2:
I am using wasm-pack 0.12.1
and cargo 1.74.0-nightly (925280f02 2023-08-25)
and yes, I built the WASM package using wasm-pack build --target web
Also note that the same function in single-thread (so without using thread::spawn
works well in the browser, so the issue really seems to be linked to multi-threading.
🤔 Expected Behavior
Front-end should accept and return and show correct value. (for example 0
for Cx=0
and Cy=1
)
👟 Steps to reproduce
You can clone my repo : , check you installed the correct dependencies in Readme (only the cargo
and just
ones are needed for this example)
Then use just wp
followed by just dev
(sometimes for some reason I must try just dev
for twice f compilation fails on first try) and try any example for inputs of Cx
and Cy
, for example enter 0
in Cx
textbox and 1
for Cy
.
🌍 Your environment
Include the relevant details of your environment. wasm-pack version: 0.12.1 rustc version: 1.74.0-nightly (84a9f4c6e 2023-08-29)
@jat9292 Hello!
Correct me if I am wrong, however I am pretty sure WASM still does not support multithreading.
https://github.com/WebAssembly/threads
I think there are some workarounds however, there was a nasty security issue found in x86 processors that made the JavaScript SharedArrayBuffer
unsafe makes multithreading hard to my understanding. I think browsers are still requiring you to opt-in for SharedArrayBuffer support. For example in Chrome you have to have sandboxing enabled which is only for Desktop at the moment (again someone correct me if I am wrong!).
Thank you. I was not really aware of this. I thought it was possible, as I was just following the official documentation of wasm-bindgen : https://rustwasm.github.io/docs/wasm-bindgen/examples/raytrace.html
@jat9292 I think it is possible using WebWorkers and SharedArrayBuffer, and probably how wasm-bindgen is implementing it. However as I mentioned support may be spotty.
https://web.dev/webassembly-threads/#rust
This article does an excellent job explaining the caveats and how it works! As threading with WebWorkers is not native threading, we can assume that std::thread
will not work.
Personally, all the added complexity may not be worth the performance boost you may get from multithreading. Definitely worth a shot though!
I am by no means an expert, so I think it would be best we get some other opinions here too.