bytecodealliance / wasmtime

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

Wasm component module debugging - failure to step into the source code #9426

Open ggjjj opened 3 days ago

ggjjj commented 3 days ago

https://github.com/bytecodealliance/wasm-tools/issues/1854

I am using a rust application that launches the wasmtime with debug_info() set to true and loads a WASM module that implements component module.

I use wasm-tools to get the module adapted to wasi by wasm-tools component new ./target/wasm32-wasip1/debug/module1.wasm -o ./tests/data/wasm-modules/processor-module1-$(VERSION).wasm --adapt wasi_snapshot_preview1.reactor.wasm

I also confirmed that the wasm-tools objdump to see that the debug_info information exists.

now once I launch the debugger for the rust application, I am only able to step into a call() function and but not in the wasm module source code.

is there any other step am I missing?

ggjjj commented 3 days ago

Configuration of wasmtime engine

let mut engine_config = Config::new(); engine_config .debug_info(true) .cranelift_opt_level(OptLevel::None) .wasm_component_model(true);

ggjjj commented 3 days ago

wasm-tools objdump of the module1 in question

https://github.com/bytecodealliance/wasm-tools/issues/1854#issuecomment-2400748393

ggjjj commented 3 days ago

Do I need to include this feature "debug-builtins" in wasmtime crate to enable the debug symbols?

ggjjj commented 3 days ago

well adding the crate feature also did not help

alexcrichton commented 3 days ago

Would you be able to share snippets of the component/embedding in question? Or perhaps a snippet using the wasmtime CLI? It sounds like you're doing everything right, so it may come down to the details as to why this isn't working

ggjjj commented 3 days ago

Module Code


mod map_fah_to_cel {
    wit_bindgen::generate!({ path: "xxx", world "map-iml",});
    // we also use some SDK elements for the exports
    impl exports::xx:xx::xx:xx for Module {
    fn process(message_input) -> message_output
    }
    export!(Module);
}
ggjjj commented 3 days ago

App code that launches the runtime and loads the module and I am debugging this app

fn main() {
   thread::scope(|scope| {
        /*
         *  As wasm runtime & module have to be running on the same OS thread,
         *  use new_current_thread() to build a tokio runtime with the current
         *  thread scheduler selected.
         */
        let runtime = runtime::Builder::new_current_thread()
            .enable_all()
            .build()
            .unwrap();

        runtime.block_on(async_main(scope));
    });
}

async fn async_main(scope) {
   let mut engine_config = Config::new();
    engine_config
        .debug_info(true)
        .cranelift_opt_level(OptLevel::None)
        .wasm_component_model(true);
    let wasm_file_name: &str = "../../tests/data/wasm-modules/processor-module1-v1.wasm";
    {
         let wasm_component_info = &mut *wasm_component_info.lock();
         wasm_component_info.insert_component(&wasm_module_id, wasm_file_name.to_owned());
    }
// insert_wasm_module()
// call_map_fn()
// wait for wasm device manager by join()
}
ggjjj commented 3 days ago

My goal is to step into the source code of process() when the call_map_fn() is executed.

fitzgen commented 2 days ago

@ggjjj I appreciate that you provided some source code here, but it is incomplete and contains syntactical errors (eg no type on async_main's parameter).

Could you provide a git repo containing a fully self contained example that we can simply clone as well as detailed steps reproduce with exactly that git repo? Something like the following:

Minimal test case: url-of-git-repo

Steps to reproduce:

* clone git repo
* Run `cargo component build` inside the git repo
* Run `lldb -- wasmtime run -g path/to/test.wasm`
* step 5 times, until you reach the `foo` function

Expected Results

* You stepped through the `a.wasm::bar` function

Actual Results

* You never stepped through the `a.wasm::bar` function

The easier you can make it to reproduce the bug exactly, without needing to fix source code that doesn't build or infer steps that are implied but not explicitly described, the better we can help you and diagnose/resolve the bug that you are seeing.

Thanks!

ggjjj commented 2 days ago

I understand but we are working on private code. so is there any way I can debug this further? @fitzgen

fitzgen commented 2 days ago

Have you tried making a minimal reproducer that doesn't contain your private code?

ggjjj commented 2 days ago

I am trying that. Is this a sample that you recommend?

https://github.com/bytecodealliance/component-docs/blob/main/component-model/examples/example-host/src/add.rs

fitzgen commented 2 days ago

If you can get that example to reproduce your issue, then that sounds great. If you can't get that example to reproduce your issue, then I'd suggest trying to make calls and link modules/components together in a similar shape as your private code in an effort to find something that will reproduce the bug.

ggjjj commented 2 days ago

Sample tried - https://github.com/bytecodealliance/wasmtime/tree/main/examples/component

Steps followed

  1. cargo build -p example-component-wasm --target wasm32-unknown-unknown
  2. cargo run --example component

I was succesfully able to step into source code in guest.rs

Next I switched to wasm32-wasip1 target

Steps followed

  1. cargo build -p example-component-wasm --target wasm32-wasip1
  2. cargo run --example component

**Error: failed to decode world from module

Caused by: 0: module was not valid 1: failed to resolve import wasi_snapshot_preview1::fd_write 2: module requires an import interface named `wasi_snapshot_preview1**

ggjjj commented 2 days ago

My goal was to convert the module to adapt to wasi-preview1

by

wasm-tools component new ./target/wasm32-wasip1/debug/guest.wasm -o ./target/wasm32-wasip1/debug/guest-wasi.wasm --adapt wasi_snapshot_preview1.reactor.wasm

and use guest-wasi.wasm to load in main.rs of component But I couldn't get to this step

ggjjj commented 2 days ago

I tried to use the guest-wasi.wasm in line53 of main.rs after the above wasm-tools command

let component = convert_to_component("target/wasm32-wasip1/debug/guest-wasi.wasm")?; while running it, I got this error

**Error: decoding a component is not supported**
ggjjj commented 2 days ago

I used 25.0.2 snapshot file https://github.com/bytecodealliance/wasmtime/releases/download/v25.0.2/wasi_snapshot_preview1.reactor.wasm

ggjjj commented 2 days ago

May I know why 26.0.0 is wasmtime version when only 25.0.2 is released?

ggjjj commented 1 day ago

@fitzgen Hey Nick did you get a chance to look at this one?

alexcrichton commented 1 day ago

@ggjjj it looks like there's a lot going on here with quite a few possibilities of what could be going wrong. We can try to piece together everything from the snippets of information you're posting but it'd be much more helpful to us as maintainers if you're able to do what Nick mentioned above with having a reproducible set of steps. It looks like you're trying a lot of things all at once and each thing is failing in different ways which may be unrelated to the original issue

ggjjj commented 13 hours ago

Agree and apologize for including some many of the methods I tried in once. ok let me start step by step.

Goal 1 - Try the component example with wasm32-wasip1.

Minimal test case: url-of-git-repo

Steps to reproduce:

Expected Results

Actual Results

Error: failed to decode world from module

Caused by:
    0: module was not valid
    1: failed to resolve import `wasi_snapshot_preview1::fd_write`
    2: module requires an import interface named `wasi_snapshot_preview1`