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 wpfollowed by just dev (sometimes for some reason I must try just devfor 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.