wasm-bindgen
wasm-bindgen copied to clipboard
Support DWARF in wasm-bindgen
Motivation
Chrome, Firefox and now also Sentry support DWARF for WebAssembly as debug format. In particularly for crash reporting systems like Sentry DWARF is a very important tool to create accurate stack traces for production builds of web assembly applications.
This issue was previously brought up in #1981.
Proposed Solution
Most likely the bulk of the implementation will be in walrus (see https://github.com/rustwasm/walrus/issues/67).
Just hoping for an update as this would be really handy for debugging WASM performance issues. Thx
After some experiments, I find it's possible to show Rust code in the Chrome DevTools with the following steps:
- add a
--keep-debug
inwasm-bindgen
when building the wasm file, i.e.wasm-bindgen --keep-debug --out-dir ...
- install a C++ chrome extension and enable DWARF support feature in chrome dev tools: https://developer.chrome.com/blog/wasm-debugging-2020/?utm_source=devtools
Then the rust code can show up in the dev tools, but other functionalities such as setting breakpoints and evaluating rust code, are broken:
![wecom-temp-bcb7d09421dfc8d9b0d40550932bdf05](https://user-images.githubusercontent.com/2306105/158933271-a8171d22-0829-4dfb-ba28-037df59d3cfa.png)
It seems the DWARF info is kept when using wasm-bindgen with --keep-debug
, but chrome doesn't fully support the dwarf debugging features for rust code.
It seems more like the debug info is "broken" after wasm-bindgen processes it, as in enough to make the source show up, but not enough for Chrome to handle it.
It seems more like the debug info is "broken" after wasm-bindgen processes it, as in enough to make the source show up, but not enough for Chrome to handle it.
The extension is for C++ only, and you can see when I try to evaluate ElementsManager::get_static()
in console, it takes the string as C++ code and says it's an invalid one. My guess is that maybe the dwarf info is correct, but it's the C++ extension that cannot understand rust code. I hope maybe someone inside the extension project or wasm-bindgen can give some concrete information about it.
Yeah, calling methods and stuff almost definitely won't work, but local variables and their fields, and breakpoints are all things that should work and last I tested DO work... if you don't use wasm-bindgen. So that still seems like a strong indication that the dwarf is broken.
@CryZe did breakpoints work for you?? The devtools find my rust code but none of the standard library or cargo packages. They are all prefixed like /cargo/...
or /rustc/...
but none of the standard library or cargo packages. They are all prefixed like
/cargo/...
or/rustc/...
It's expected and happens because standard library in Rust is prebuilt on CI with those paths hardcoded. You can remap them to either github or your local rust-src paths via the extension settings.
But, either way, the breakpoints won't work at the moment because, as mentioned above, DWARF remapping is not implemented in wasm-bindgen.
got it! thankyou for the quick response 🙏
But, either way, the breakpoints won't work at the moment because, as mentioned above, DWARF remapping is not implemented in wasm-bindgen.
Should probably clarify that this is only if you use wasm-bindgen. If you use raw Wasm, it will work (but that's uncommon on the web).
ah i got. because wasm-bindgen is actually changing the wasm when it generates the bindings but its not changing the DWARF so nothing matches up.
Regular wasm doesnt do that so its not a problem
Note: with a few changes, I managed to successfully step through wasm-bindgen
'd Rust code in Chrome using @nokotan's fork of walrus
. See https://github.com/rustwasm/walrus/pull/231#issuecomment-1431438647.
However, that fix is very much non-production ready. As I mentioned in the comment linked above, it requires several forks of existing libraries, including wit-walrus
which is not maintained anymore (since WIT no longer seem active). wasm-bindgen-cli-support
would need a lot of work to drop the dependencies on WIT-related crates, so for now that dependency needs to stay. Once that's done, we'd need to make sure the PR I linked above would be merged. Since DWARF doesn't seem to work well with Chrome (at least on Windows), we'd also need make our own version of wasm-sourcemap.py
(since a Python dependency on top of Rust and JS would be a bit much).
Note: I'd like to get more involved with wasm-bindgen
(and its dependencies), so if any maintainer sees this and can point me to tasks that would help make this possible, please do!
Since DWARF doesn't seem to work well with Chrome (at least on Windows), we'd also need make our own version of
wasm-sourcemap.py
(since a Python dependency on top of Rust and JS would be a bit much).
Someone has now built this, and playing around with it locally it seems like it works well: https://github.com/mtolmacs/wasm2map
@Cldfire FWIW that comment above was mistaken, DWARF does work well with Chrome directly: https://github.com/rustwasm/walrus/pull/231#issuecomment-1431619795
Yea, I can also confirm that DWARF works well for me with Chrome, at least on macOS (M1).
VS Code's JavaScript debugger is also now DWARF aware (nightly build today, and to stable in 2 weeks). Support here would make targeting wasm from Rust much more pleasant for VS/Code folks 🙂
Just for visibility: this is currently only blocked on https://github.com/rustwasm/walrus/issues/247.
for visibility: https://github.com/rustwasm/walrus/issues/247 has been fixed.
Awesome! Can't wait to give this a shot on Monday... so I'll probably try it this weekend 😄
Well..... @connor4312 ????? I'm on tenterhooks and I believe this is more important than Thanksgiving because if it works I can give thanks!
How is it decided when new wasm-bindgen versions are released? On demand? Looking forward to giving the next release a try 😎
I'm on tenterhooks and I believe this is more important than Thanksgiving because if it works I can give thanks!
At cursory investigation, things work with a few caveats:
- Publishing of packages still needs to happen. Also, I can only get symbols working if I invoke wasm-bindgen directly with
--keep-debug
, not via the more commonwasm-pack
, but maybe this'll be fixed when things are published? - Locations work in the Chrome C++ extension but they're off in VS Code's debugger. This is likely on my side to fix; we consume the guts of the Chrome plugin to do the DWARF heavy lifting so I'm probably just holding it wrong. I will look after the holiday.
How is it decided when new wasm-bindgen versions are released? On demand?
@haraldreingruber-dedalus I think this should be released. Or maybe I am mistaken.
Fixed in VS Code, will be released in about 1.5 weeks from today
Will be looking forward to a new version of wasm-bindgen/wasm-pack so we can update our docs with Rust debugging instructions :)
@connor4312 It looks like the call stack name is not taken from DWARF but rather from the names section? Is that a currently known limitation?
that's formed from asking the worker for getFunctionInfo
, which is the same (from what I understand) as what the devtools extension does. I get the same result there, maybe the issue is upstream?
Ah weird, could be. It's been couple of years since I tried Rust-produced Wasm in DevTools. I guess they'd need Rust-specific demangling to omit it. Not a big deal either way, thanks for working on this!
@connor4312 thanks so much for the work on this! I kind of expected this to be released to vscode-insiders but maybe not yet? rustwasm/walrus dependency upgrades are now in the 0.2.89 release (diff)
It's in tomorrow's Insiders
Thanks for the wonderful work. I played for a while and found the following:
- breakpoint, stepping: works nicely, great
- local variable inspecting: it shows
undefined
for every local variable, no idea if it's something I did wrong: - function arguments inspecting: arguments are
undefined
exceptself
.self
can be fully expanded, and someowned
values can be inspected properly, but boxed values are hidden behind pointers, which makes them hard to be inspected: