I want to add a handler function to Wasmtime to be called when the wasm module calls an imprted function such as Wasi libc functions. So, wasmtime transfers the control to my handler and then my handler calls the imported function. Can you please help me how I can implement this handler for wasmtime?
Does Store::call_hook
do the trick for you ?
Thanks for your reply.
I need the mechanism like ptrace, is it the similar to it? I couldn't find an example for it
Wasmtime doesn't support singlestepping through a wasm function. You will likely need a wasm interpreter (as opposed to compiler) for that.
I think my comment wasn't clear, and made you confuse, sorry for that.
Let me clarify it:
This is what I need to do:
1. a wasm module calls a wasi function or another imported function
2. Regardless of which function was called, my custom function should be called (like a proxy) and this function should access to all parameter’s values
3. Then my custom function can change parameters values and then calls the requested wasi function with the changed values
Is it possible to add this functionality to Wasmtime?
This should be possibly by defining your own version of a function within a Linker
. Calling the original function is a bit wonky but you can use Linker::get
to get the previous version of the function to call after you've applied your ahead-of-time filtering logic. Additionally many items inserted into a Linker
are also provided as free functions (e.g. in the case of WASI I think that should be the case, or we can at least make that be the case)
@Alex Crichton great! thanks for your reply. I should study more about the linker to get familiar with it to understand how I can implement it. thanks!
@Alex Crichton I found out how I can add my function to a linker. But it is still confusing to me how I can access to imported function parameters when a call happens. Can you please help me with accessing argument's values of calling import functions? You mentioned that it is possible to use Linker::get to get the previous version of the function. Is this function (get in linker) called when an import function called in the wasm module? How can this function access to imported function parameters? Can you clarify your answer a little bit more?
Sorry if my question is silly because I just started to learn wasmtime structure.
Hm I'm not sure I understand, when a function is added to a Linker
it's added as a closure, and the parameters to the wasm function are the parameters to the closure, so I'm not sure how else you'd like access to the parameters?
For acquiring the previous version you'd probably get the current version of the function, then close over that in the definition of the new function. Something like:
let mut linker = ...;
let prev_func = linker.get(&mut store, "foo", "bar").unwrap().into_func().unwrap();
linker.define("foo", "bar", |arg: u32| {
println!("got: {}", arg);
prev_func.call(&mut store, arg)?;
Ok(())
})?;
or something like that
Thanks for your reply.
I wanted my function to act like a transparent proxy for a wasm module and call when a wasi function has been called. But right now, based on your sample code, I think what you mean is that I have to import my custom function into the wasm module and call it instead of wasi function and then my custom function calls the wasi (previous) function. Is it right?
I have another question, is there any function in wasmtime that calls when a wasi function is called by a wasm module? I mean a function which transfer the control to the wasi functions in wasi_snapshot_preview1.
No what I'm describing is shadowing a function in a linker where you redefine a previous item (e.g. a previously defined wasi function) with your own custom function, so when a wasm module calls that wasi function it calls your function instead.
There are some simliar features to your second question but I don't think we have one precisely for that.
I'd probably recommend studying the API documentation of the Linker
type and additionally looking more into how WASI is implemented in Wasmtime today using Linker
. Putting those two together will probably give you a better picture about how to implement what you're thinking and what the limitations are.
Thanks for your solution. It worked and I could shadow a wasi function. However I had to use linker.func_wap instead of define (define didn’t work). I added my implementation to RunCommand implementation in src/commands/run.rs file.
But I still have trouble with calling the previous function. For example, I got these errors when I wanted to shadow args_sizes_get function which is a function without any argument. Do you know what is wrong with my implementation?
linker.func_wrap("wasi_snapshot_preview1", "args_sizes_get", || -> (i32,i32) {
| ^^^^^^^^^^^^^^^ this closure implements FnOnce , not Fn the requirement to implement Fn derives from here
prev_func.call(store,&[],&mut []);
closure is FnOnce because it moves the variable store out of its environment
error[E0277]: RefCell<wasmtime_wasi_nn::ctx::Ctx> cannot be shared between threads safely
--> src/commands/run.rs:209:20
```
Last updated: Dec 23 2024 at 13:07 UTC