-
Notifications
You must be signed in to change notification settings - Fork 921
Description
Project Info
Project A
As the main project, it is responsible for loading the .wasm file and running it.
- Rust:2021 rustc 1.84.1 (e71f9a9a9 2025-01-27)
- Wasmer: 5.0.4
- wasix is supported
Project B
Use the [cargo wasix build --release] command to compile into a .wasm file.
- Rust:2021 rustc 1.84.1 (e71f9a9a9 2025-01-27)
- Tokio:https://github.com/wasix-org/tokio.git branch = "wasix-1.35.1"
My Code
Project B
I performed two operations in project B, declared and used the import function [my_host_fn], and used std::thread::spawn to generate a new thread. The code is as follows:
########################################################
#[no_mangle]
extern "C" {
pub fn my_host_fn();
}
#[no_mangle]
pub extern "C" fn _start() {
println!("_start hello hello");
std::thread::spawn(move || println!("std::thread::spawn hello hello"));
unsafe { my_host_fn() };
}
########################################################
Project A
Next is Project A, where I refer to this example:
https://github.com/wasmerio/wasmer/blob/e36b898895922593cd3b9971e5fae5a915951146/examples/wasi_manual_setup.rs
The code is as follows:
########################################################
#[derive(Clone)]
struct Env {}
// Let's declare the Wasm module with the text representation.
let wasm_bytes = std::fs::read("./project_b.wasm")?;
// Create a Store.
let mut store = Store::default();
println!("Compiling module...");
// Let's compile the Wasm module.
let module = Module::new(&store, wasm_bytes)?;
println!("Starting `tokio` runtime...");
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
let _guard = runtime.enter();
let mut wasi_env = WasiEnv::builder("hello").finalize(&mut store)?;
let env = FunctionEnv::new(&mut store, Env {});
let mut import_object = wasi_env.import_object_for_all_wasi_versions(&mut store, &module)?;
let memory_type = module.imports().memories().next().map(|a| *a.ty()).unwrap();
let memory = Memory::new(&mut store, memory_type)?;
import_object.define("env", "memory", memory.clone());
import_object.extend(&imports! {
"env" => {
"my_host_fn" => Function::new_typed_with_env(&mut store, &env, |env: FunctionEnvMut<Env>|{
println!("Calling `my_host_fn,my_host_fn`...");
}),
}
});
let instance = Instance::new(&mut store, &module, &import_object)?;
wasi_env.initialize_with_memory(&mut store, instance.clone(), Some(memory.clone()), true)?;
println!("Call WASI `xxx` function...");
// And we just call the `_start` function!
let start: TypedFunction<(), ()> =
instance.exports.get_function("_start")?.typed(&mut store)?;
start.call(&mut store)?;
println!("End Call WASI `xxx` function...");
sleep(Duration::from_secs(100));
wasi_env.on_exit(&mut store, None);
########################################################
Error
i execute WASM using project A, and console error is as follows:
thread '<unnamed>' panicked at /Users/runner/work/rust/rust/wasix-rust/library/std/src/thread/mod.rs:734:29: failed to spawn thread: Os { code: 6, kind: WouldBlock, message: "Resource temporarily unavailable" } note: run with RUST_BACKTRACE=1 environment variable to display a backtrace Error: RuntimeError { source: Wasm { pc: 4443425784, backtrace: 0: <unknown> 1: <unknown> 2: <unknown> 3: <unknown> 4: <unknown> 5: <unknown> 6: <unknown> 7: <unknown> 8: <unknown> , signal_trap: None }, wasm_trace: [] }
and debug it,i found error source:
Lines 153 to 157 in cbfc980
| return Err(LinkError::Import( | |
| import.module().to_string(), | |
| import.name().to_string(), | |
| ImportError::UnknownImport(import.ty().clone()), | |
| )); |
this image is thread stack when error happened

my conclusion
because [env.my_host_fn] is missing when wasmer execute
the root cause seems when spawn a new thread in wasm, wasmer will create a new instance with new imports ,but did not inherit original instance‘s imports
focus on new_with_store, create new import_object and new memory in new_with_store:
wasmer/lib/wasix/src/state/func_env.rs
Line 41 in f5a5e65
| pub fn new_with_store( |
my confuse
- why spawn a new thread must be auto create new instance by wasmer? and new instance did not inherit from original instance?
- If the existing wasmer code is correct, how should I use multithreading and host function calls in wasm at the same time?