For a Wasm that exports an alloc function so that the host can alloc memory and then copy bytes into guest:
#[no_mangle]
pub unsafe extern "C" fn alloc(len: usize, align: usize) -> *mut u8 {
std::alloc::alloc(std::alloc::Layout::from_size_align_unchecked(len, align))
}
When the host using the Rust embedding API to call this function in wasmtime, and wmemcheck
is enabled, I got an error:
Error: error while executing at wasm backtrace:
0: 0x83 - test_wmemcheck.wasm!alloc
1: 0x2a68 - test_wmemcheck.wasm!alloc.command_exportCaused by:
Load out of bounds at addr 0x100000 of size 1
I have reduced both the host code and the guest Wasm code to a minimal example, and it still reports error. What is the reason behind this?
Could you post the minimal example?
The host code is from the example code in the main doc
use anyhow::Result;
use wasmtime::*;
fn main() -> Result<()> {
let engine = Engine::new(&Config::new().wmemcheck(true))?;
let module = Module::from_file(
&engine,
"/home/x/wasm32-unknown-unknown/release/test_wmemcheck.wasm",
)?;
// Create a `Linker` which will be later used to instantiate this module.
// Host functionality is defined by name within the `Linker`.
let mut linker = Linker::new(&engine);
linker.func_wrap(
"host",
"host_func",
|caller: Caller<'_, u32>, param: i32| {
println!("Got {} from WebAssembly", param);
println!("my host state is: {}", caller.data());
},
)?;
// All wasm objects operate within the context of a "store". Each
// `Store` has a type parameter to store host-specific data, which in
// this case we're using `4` for.
let mut store = Store::new(&engine, 4);
let instance = linker.instantiate(&mut store, &module)?;
let alloc = instance.get_typed_func::<(u32, u32), (u32)>(&mut store, "alloc")?;
// And finally we can call the wasm!
alloc.call(&mut store, (64, 4))?;
Ok(())
}
The wasm code is compiled to wasip1 and unknown-unknown and both reports error:
/// Allocate memory.
///
/// # Safety
///
/// See [`std::alloc::GlobalAlloc::alloc`].
#[no_mangle]
pub unsafe extern "C" fn alloc(len: usize, align: usize) -> *mut u8 {
std::alloc::alloc(std::alloc::Layout::from_size_align_unchecked(len, align))
}
/// Deallocate memory.
///
/// # Safety
///
/// See [`std::alloc::GlobalAlloc::dealloc`].
#[no_mangle]
pub unsafe extern "C" fn dealloc(ptr: *mut u8, len: usize, align: usize) {
std::alloc::dealloc(
ptr,
std::alloc::Layout::from_size_align_unchecked(len, align),
);
}
Last updated: Jan 24 2025 at 00:11 UTC