wasm-pack icon indicating copy to clipboard operation
wasm-pack copied to clipboard

Bug in the browser when using wasm-pack for a multithreaded Rust function

Open jat9292 opened this issue 1 year ago • 3 comments

🐛 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 avatar Sep 07 '23 16:09 jat9292

@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!).

tronicboy1 avatar Sep 14 '23 06:09 tronicboy1

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 avatar Sep 14 '23 07:09 jat9292

@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.

tronicboy1 avatar Sep 15 '23 01:09 tronicboy1