Stream: wasmtime

Topic: debugging wasmtime serve


view this post on Zulip Ralph (Mar 06 2024 at 13:47):

Anyone here have experience using lldb and gdb with the wasmtime serve command? I can get lldb and gdb started, but the objective is NOT to debug wasmtime itself, but rather the running wasm and using dwarf symbols to map that to the original source code.

view this post on Zulip Ralph (Mar 06 2024 at 13:47):

I can get gdb and lldb started easily enough, but because the serve command doesn't seem to open the endpoint, I can't hit it.

view this post on Zulip Ralph (Mar 06 2024 at 13:48):

I do get a wonderful list of tokio processes, however, so I've got that going for me.....

view this post on Zulip Ralph (Mar 06 2024 at 13:50):

I have this to follow: https://docs.wasmtime.dev/examples-rust-debugging.html, though my source code is C, so I'll need to ensure that /opt/wasi-sdk/bin/clang is building dwarf in of course.

view this post on Zulip Scott Waye (Mar 09 2024 at 02:02):

NOt tried serve but for source debugging I do

c:\"Program Files"\llvm\bin\lldb target\debug\wasmtime.exe

Then

 process launch --stop-at-entry -- -D debug-info c:\tmp\console\bin\Debug\net8.0\wasi-wasm\native\console.wasm
breakpoint set --file 1.c --line 5
c

view this post on Zulip Ralph (Mar 10 2024 at 19:24):

do you get dwarf symbols in return? I can GET dwarf info from core modules, but seemingly I'm defied by compoents:

view this post on Zulip Ralph (Mar 10 2024 at 19:25):

Core wasm:

view this post on Zulip Ralph (Mar 10 2024 at 19:25):

squillace@idiopath:~/work/witlldb/hello-c$ lldb -- wasmtime -D debug-info=y foo.wasm
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'lldb.embedded_interpreter'
(lldb) target create "wasmtime"
Current executable set to 'wasmtime' (x86_64).
(lldb) settings set -- target.run-args "-D" "debug-info=y" "foo.wasm"
(lldb) breakpoint set --name main
Breakpoint 1: where = wasmtime`main, address = 0x00000000004af180
(lldb) run
Process 181137 launched: '/home/squillace/.wasmtime/bin/wasmtime' (x86_64)
Process 181137 stopped

view this post on Zulip Ralph (Mar 10 2024 at 19:25):

no problem there

view this post on Zulip Ralph (Mar 10 2024 at 19:27):

but with components, I can't grab the function name. The core wasm name was "main" but the component export function is "__main_void". I tried both:

view this post on Zulip Ralph (Mar 10 2024 at 19:29):

squillace@idiopath:~/work/witlldb/hello-c$ lldb -- wasmtime run -D debug-info=y comfoonent.wasm
(lldb) target create "wasmtime"
Current executable set to 'wasmtime' (x86_64).
(lldb) settings set -- target.run-args "run" "-D" "debug-info=y" "comfoonent.wasm"
(lldb) breakpoint set -name __main_void
(lldb) run
Process 182996 launched: '/home/squillace/.wasmtime/bin/wasmtime' (x86_64)
hello from everywhere!
Process 182996 exited with status = 0 (0x00000000)
(lldb) exit

squillace@idiopath:~/work/witlldb/hello-c$ lldb -- wasmtime run -D debug-info=y comfoonent.wasm
(lldb) target create "wasmtime"
Current executable set to 'wasmtime' (x86_64).
(lldb) settings set -- target.run-args "run" "-D" "debug-info=y" "comfoonent.wasm"
(lldb) breakpoint set --name main
(lldb) run
<snikp>
(lldb) c
Process 183439 resuming
hello from everywhere!
Process 183439 exited with status = 0 (0x00000000)

view this post on Zulip Ralph (Mar 10 2024 at 19:32):

trying to do it by setting lines and files ALSO doesn't work, but does for core wasm:

view this post on Zulip Ralph (Mar 10 2024 at 19:32):

squillace@idiopath:~/work/witlldb/hello-c$ lldb -- wasmtime run -D debug-info=y comfoonent.wasm
(lldb) settings set -- target.run-args "run" "-D" "debug-info=y" "comfoonent.wasm"
(lldb) breakpoint set -f foo.rs -l 2
Breakpoint 1: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) run
Process 187505 launched: '/home/squillace/.wasmtime/bin/wasmtime' (x86_64)
hello from everywhere!
Process 187505 exited with status = 0 (0x00000000)
(lldb) exit

squillace@idiopath:~/work/witlldb/hello-c$ lldb -- wasmtime -D debug-info=y foo.wasm
(lldb) settings set -- target.run-args "-D" "debug-info=y" "foo.wasm"
(lldb) breakpoint set -f foo.rs -l 2
Breakpoint 1: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) run
Process 187877 launched: '/home/squillace/.wasmtime/bin/wasmtime' (x86_64)
1 location added to breakpoint 1
Process 187877 stopped

view this post on Zulip Ralph (Mar 10 2024 at 19:54):

And I can wire that stuff up now.... But the components elude me.

view this post on Zulip Ralph (Mar 10 2024 at 19:54):

image.png

view this post on Zulip Scott Waye (Mar 10 2024 at 23:41):

I see, its compoents. I've not got there yet, but I will also be looking at it when I can get https://github.com/bytecodealliance/wasmtime/pull/8055 into a fit state.

Wasmtime supports debugging with DWARF, and this PR adds initial support for DWARF fission. DWARF fission has advantages in linking and wasm size (https://developer.chrome.com/blog/faster-wasm-deb...

view this post on Zulip Ralph (Mar 11 2024 at 13:11):

that is a very good thing to do

view this post on Zulip Ralph (Mar 11 2024 at 13:12):

so far as I can see, the current tooling strips out dwarf

view this post on Zulip Ralph (Mar 11 2024 at 13:12):

if I do the core module:

view this post on Zulip Ralph (Mar 11 2024 at 13:12):

squillace@idiopath:~/work/hello-wasi-http-go$ wasm-tools objdump main.wasm
types | 0xa - 0x63 | 89 bytes | 14 count
imports | 0x66 - 0x2f2 | 652 bytes | 13 count
functions | 0x2f4 - 0x342 | 78 bytes | 77 count
tables | 0x344 - 0x349 | 5 bytes | 1 count
memories | 0x34b - 0x34e | 3 bytes | 1 count
globals | 0x350 - 0x362 | 18 bytes | 3 count
exports | 0x365 - 0x473 | 270 bytes | 14 count
elements | 0x475 - 0x47e | 9 bytes | 1 count
data count | 0x480 - 0x481 | 1 bytes | 1 count
code | 0x485 - 0xa329 | 40612 bytes | 77 count
data | 0xa32c - 0xae8e | 2914 bytes | 3 count
custom "name" | 0xae96 - 0xba8e | 3064 bytes | 1 count
custom ".debug_info" | 0xba9e - 0x1fd2a | 82572 bytes | 1 count
custom ".debug_pubtypes" | 0x1fd3d - 0x21dc1 | 8324 bytes | 1 count
custom ".debug_loc" | 0x21dd0 - 0x268d7 | 19207 bytes | 1 count
custom ".debug_ranges" | 0x268e8 - 0x277c0 | 3800 bytes | 1 count
custom ".debug_aranges" | 0x277d1 - 0x27821 | 80 bytes | 1 count
custom ".debug_abbrev" | 0x27832 - 0x28457 | 3109 bytes | 1 count
custom ".debug_line" | 0x28467 - 0x2ecb6 | 26703 bytes | 1 count
custom ".debug_str" | 0x2ecc5 - 0x3e2a5 | 62944 bytes | 1 count
custom ".debug_pubnames" | 0x3e2b9 - 0x4ca6e | 59317 bytes | 1 count
custom "producers" | 0x4ca7b - 0x4cb0e | 147 bytes | 1 count
custom "target_features" | 0x4cb20 - 0x4cb5e | 62 bytes | 1 count

view this post on Zulip Ralph (Mar 11 2024 at 13:12):

in short, I got the debug info

view this post on Zulip Ralph (Mar 11 2024 at 13:13):

but objdump doesn't show anything in the component version of the same core module:

view this post on Zulip Ralph (Mar 11 2024 at 13:13):

component imports | 0x154f - 0x1572 | 35 bytes | 1 count
module | 0x1576 - 0x1522a6 | 1379632 bytes | 1 count
------ start module 0 -------------
types | 0x1581 - 0x17cd | 588 bytes | 69 count
imports | 0x17d0 - 0x1bf7 | 1063 bytes | 24 count
functions | 0x1bfa - 0x1ed3 | 729 bytes | 727 count
tables | 0x1ed5 - 0x1eda | 5 bytes | 1 count
memories | 0x1edc - 0x1edf | 3 bytes | 1 count
globals | 0x1ee1 - 0x1ef3 | 18 bytes | 3 count
exports | 0x1ef6 - 0x2011 | 283 bytes | 14 count
elements | 0x2013 - 0x2025 | 18 bytes | 1 count
data count | 0x2027 - 0x2028 | 1 bytes | 1 count
code | 0x202c - 0x14154b | 1307935 bytes | 727 count
data | 0x14154f - 0x148ec9 | 31098 bytes | 2 count
custom "name" | 0x148ed2 - 0x1521a1 | 37583 bytes | 1 count
custom "producers" | 0x1521ae - 0x152256 | 168 bytes | 1 count
custom "target_features" | 0x152268 - 0x1522a6 | 62 bytes | 1 count
------ end module 0 -------------
module | 0x1522aa - 0x15ae70 | 35782 bytes | 1 count
------ start module 1 -------------
types | 0x1522b5 - 0x152338 | 131 bytes | 20 count
imports | 0x15233b - 0x152b4a | 2063 bytes | 41 count
functions | 0x152b4c - 0x152b92 | 70 bytes | 69 count
globals | 0x152b94 - 0x152ba4 | 16 bytes | 3 count
exports | 0x152ba7 - 0x152caa | 259 bytes | 17 count
code | 0x152cae - 0x15881a | 23404 bytes | 69 count
custom "name" | 0x158822 - 0x15ae21 | 9727 bytes | 1 count
custom "producers" | 0x15ae2d - 0x15ae70 | 67 bytes | 1 count
------ end module 1 -------------
module | 0x15ae73 - 0x15bb93 | 3360 bytes | 1 count
------ start module 2 -------------
types | 0x15ae7d - 0x15aeea | 109 bytes | 15 count
functions | 0x15aeec - 0x15af17 | 43 bytes | 42 count
tables | 0x15af19 - 0x15af1e | 5 bytes | 1 count
exports | 0x15af21 - 0x15aff5 | 212 bytes | 43 count
code | 0x15aff8 - 0x15b233 | 571 bytes | 42 count
custom "producers" | 0x15b23f - 0x15b263 | 36 bytes | 1 count
custom "name" | 0x15b26b - 0x15bb93 | 2344 bytes | 1 count
------ end module 2 -------------
module | 0x15bb96 - 0x15bd92 | 508 bytes | 1 count
------ start module 3 -------------
types | 0x15bba0 - 0x15bc0d | 109 bytes | 15 count
imports | 0x15bc10 - 0x15bd12 | 258 bytes | 43 count
elements | 0x15bd14 - 0x15bd44 | 48 bytes | 1 count
custom "producers" | 0x15bd50 - 0x15bd74 | 36 bytes | 1 count
custom "name" | 0x15bd7b - 0x15bd92 | 23 bytes | 1 count
------ end module 3 -------------
core instances | 0x15bd94 - 0x15bd98 | 4 bytes | 1 count
component alias | 0x15bd9a - 0x15bdac |

view this post on Zulip Ralph (Mar 11 2024 at 13:14):

and llvm-dwarfdump sure doesn't know anything about components.

view this post on Zulip Ralph (Mar 11 2024 at 13:14):

squillace@idiopath:~/work/hello-wasi-http-go$ dump -debug-line main.component.wasm
error: main.component.wasm: invalid version number: 65549

view this post on Zulip Ralph (Mar 11 2024 at 13:35):

Scott Waye said:

I see, its compoents. I've not got there yet, but I will also be looking at it when I can get https://github.com/bytecodealliance/wasmtime/pull/8055 into a fit state.

This kind of seems like what https://github.com/WebAssembly/tool-conventions/issues/133 was for. Am I misunderstanding? Or, if I plow through the associated document, that seems more like keeping the debug sections but pointing to another location for the .dwo. How should I think about the two approaches for side-debugging symbols?

I originally brought this up in the design repo (WebAssembly/design#1306) but I believe this fits here better. For deferred symbolication on services like sentry it would be nice to be able to matc...

Last updated: Dec 23 2024 at 14:03 UTC