bytecodealliance / wasmtime

A fast and secure runtime for WebAssembly
https://wasmtime.dev/
Apache License 2.0
15.2k stars 1.28k forks source link

View variables from shared memories in debugger #7278

Open doinkythederp opened 11 months ago

doinkythederp commented 11 months ago

Thanks for filing a feature request! Please fill out the TODOs below.

Feature

I'd like to be able to see the values of the variables in my Rust code that I've compiled to WASM when debugging with LLDB. Currently when using CodeLLDB to debug Rust compiled in debug mode, the only variable present is __vmctx.

Benefit

This would make it a lot simpler to debug incorrect state in programs and generally understand a misbehaving program.

cfallin commented 11 months ago

It's possible that #6960 would fix this issue for you (it's not yet in a release -- it looks like it just missed the cutoff for 13.0 in September, but it should be included in 14.0 on Oct 20). Could you try with a build from the latest main and see if your issue still occurs?

doinkythederp commented 11 months ago

Here's what it looks like with wasmtime @ 8e00cc202f82445a42adbad6e8187e901f91833b: image image I read that it was necessary to run __vmctx->set() but it seems like that might be invalid syntax when debugging Rust?

I am using .debug_info(true) in my wasmtime config and am compiling my WASM code in debug mode.

cfallin commented 11 months ago

Are the values you're trying to show live at that location (i.e., will be used in the future)?

There is some optimization that goes on regardless of opt level just as a side-effect of going through SSA form, and register allocation; and the Rust + LLVM Wasm toolchain may be optimizing away values as well. It's hard to really say more without access to your module and a good chunk of time to dive into the IR, the DWARF, and the regalloc choices (sorry!).

bjorn3 commented 11 months ago

Does __vmctx.set() or (*__vmxtx).set() work? At least gcc switches to the rust syntax for the print command when the current frame is marked as written in rust. I don't know if that is the case with lldb too.

doinkythederp commented 11 months ago

Hi, I have an update: I've been working on getting a minimal demonstration of the situation and I stumbled upon the discovery that variables only show in the debugger menu when not using WASM threads/shared memory. For my use cases, I need WASM threads as I'm emulating the FreeRTOS task-switching mechanism. I've made a Dev Container that shows this behavior: https://github.com/doinkythederp/wasmtime-repro

doinkythederp commented 9 months ago

Hi, I'm just checking back in to ask if there are any plans to fix variable debugging when using SharedMemory. This is important to me because it limits the work I can do with WASM threads. Is this planned? Is it an issue with LLDB itself? I don't have much experience in dealing with debug info or debugger internals so I don't think I'd be able to make any required contributions myself.

abrown commented 9 months ago

@doinkythederp, thanks for the codespace reproducer. Here's what I get when I follow your instructions:

image

It looks like, as @cfallin suggested, those values are being optimized away. But when I look at the WAT there seems to be enough there for proper debugging: example.wat.txt. So perhaps something is truly wrong with the DWARF here; I remember someone mentioning that that part of the codebase needs some maintenance attention.

squillace commented 6 months ago

Yup. wasmtime 18.02. image

pgherveou commented 3 months ago

Hey there, I was trying to get this to work as well using wasmtime example, but it fails to print the variable as well, it looks like this works though when you run the program through wasmtime binary

❯ lldb --version
lldb version 17.0.6

❯ lldb --batch -o "b  fib" -o "run" -o "fr v" -o "c"  ./target/debug/examples/fib-debug
(lldb) target create "./target/debug/examples/fib-debug"
Current executable set to '/home/pg/github/wasmtime/target/debug/examples/fib-debug' (x86_64).
(lldb) b  fib
Breakpoint 1: no locations (pending).
WARNING:  Unable to resolve breakpoint to any actual locations.
(lldb) run
1 location added to breakpoint 1
warning: This version of LLDB has no plugin for the language "rust". Inspection of frame variables will be limited.
Process 1334333 stopped
* thread #1, name = 'fib-debug', stop reason = breakpoint 1.1
    frame #0: 0x00007ffff76cc275 JIT(0x7fffef400010)`fib(n=<unavailable>) at fib.rs:3:17
   1    #[no_mangle]
   2    pub extern "C" fn fib(n: u32) -> u32 {
-> 3        let mut a = 1;
   4        let mut b = 1;
   5        for _ in 0..n {
   6            let t = a;
   7            a = b;
Process 1334333 launched: '/home/pg/github/wasmtime/target/debug/examples/fib-debug' (x86_64)
(lldb) fr v
(WasmtimeVMContext *) __vmctx = <variable not available>

(unsigned int) n = <variable not available>

(lldb) c
fib(6) = 21
Process 1334333 resuming
Process 1334333 exited with status = 0 (0x00000000)
alexcrichton commented 3 months ago

@pgherveou were you running with OptLevel::None and if not can you test that?

pgherveou commented 3 months ago

@alexcrichton I am running the example code from the repo.

do you mean that I should configure the config with cranelift strategy and set cranelift_opt_level to None ?

alexcrichton commented 3 months ago

Indeed yeah, the strategy is default cranelift so you don't have to configure that unless you want, but OptLevel::None is not the default so you need to explicitly opt-in to that. This is something I just discovered myself a day or two ago, and if that fixes things for you I'll update the example/docs around this.

pgherveou commented 3 months ago

mmm the doc does say it's the default though https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html#method.cranelift_opt_level

The default value for this is OptLevel::None.

pgherveou commented 3 months ago

This does not seem to make a difference for me though, the output of the lldb script is the same as before. These are the commands that I fired:

cargo build --features debug-builtins --example fib-debug
cargo build -p example-fib-debug-wasm --target wasm32-unknown-unknown
lldb --batch -o "b  fib" -o "run" -o "fr v" -o "c"  ./target/debug/examples/fib-debug
pgherveou commented 3 months ago

Things works fine though if I simplify the fib function to something as simple as

[no_mangle]
pub extern "C" fn fib(n: u32) -> u32 {
    return n + 3;
}

The C code compiled to wasm seems to work just fine as well too.

alexcrichton commented 3 months ago

Poking around locally I'm not sure what's going on as well. I spun out the issue into https://github.com/bytecodealliance/wasmtime/issues/8752 as an isolated version of the issue you're hitting.