I'm working on a WebAssembly project with two modules (main.wasm
and env.wasm
) that use shared memory. env.wasm
exports the memory and a function, while main.wasm
imports the memory and calls the function. However, when I try to run the modules using Wasmtime, I encounter the following error:
Error: failed to run main module `main.wasm`
Caused by:
0: failed to instantiate "main.wasm"
1: unknown import: `env::memory` has not been defined
Here are my compilation commands:
For env.wasm
:
clang \
--target=wasm32-wasi-threads \
--sysroot /wasi-libc/sysroot \
-pthread \
env.c \
-o env.wasm \
-Wl,--no-entry \
-Wl,--export=process_string \
-Wl,--export-memory \
-Wl,--shared-memory \
-Wl,--initial-memory=131072 \
-Wl,--max-memory=131072
For main.wasm
:
clang \
-Wno-implicit-function-declaration \
--target=wasm32-wasi-threads \
--sysroot /wasi-libc/sysroot \
-pthread \
main.c \
-o main.wasm \
-Wl,--export=_start \
-Wl,--allow-undefined \
-Wl,--shared-memory \
-Wl,--import-memory \
-Wl,--initial-memory=131072 \
-Wl,--max-memory=131072
I'm running the modules in Wasmtime with the following command:
wasmtime --preload env=env.wasm \
main.wasm \
--invoke main \
--wasm-features=threads \
--wasi-modules=default
env.wasm
: Using wasm-objdump -x
, I confirmed that memory
is exported with (memory (;0;) 2 2 shared)
.main.wasm
: Also confirmed via wasm-objdump -x
that main.wasm
is attempting to import env::memory
with (memory (;0;) 2 2 shared)
.env
as the namespace for the memory.What could be causing Wasmtime to fail to resolve env::memory
? Are there additional flags or configurations I might have missed? Any help would be greatly appreciated!
Would you be able to share the two modules in question?
Hi Alex! Of course, here are the two modules:
main.c
#include <stdio.h>
int main(int argc, char** argv) {
const char* input_string = "Hello from main.wasm";
int response_int = process_string(input_string);
printf("Received integer from env.wasm: %d\n", response_int);
return 0;
}
env.c
#include <stdio.h>
#include <string.h>
static int my_return_integer = 66;
// Function that prints the input string and returns a int
int process_string(const char* input) {
printf("lib.wasm received string: %s\n", input);
return my_return_integer;
}
Let me know if you need further clarification!
ah looks like the problem is the _start
export of env.wasm
which causes it to be classified as a "command" and only functions can be imported from commands, not globals/memories (as command-imported functions get a fresh new instance each time)
Good point! Thanks, Alex. I used -Wl,--no-entry
and -nostartfiles
to remove the _start
function in env.wasm
. I have double-checked this using wasm-objdump
, and _start
is no longer present in the exports.
However, when I run the following command:
wasmtime --preload env=env.wasm \
main.wasm \
--invoke main \
--wasm-features=threads \
--wasi-modules=default
The program seems to hang indefinitely. Any help on resolving this issue would be greatly appreciated!
I suspect what's happening is these two modules are corrupting each other. You're loading them into the same shared memory but they're not compiled knowing the other is in the same shared memory, so they're probably stomping all over each other's stacks/data structures/rodata/data/etc
In case it's useful this is the convention for sharing memory and table(s) in an orderly way.
Hi Alex and Joel,
Thanks for the help! I’m now able to move further. However, when I run the command:
wasmtime --preload env=env.wasm \
main.wasm \
--invoke main \
--wasm-features=threads \
--wasi-modules=default
I get some output along with the following error message:
Error: failed to run main module `main.wasm`
Caused by:
0: failed to invoke command default
1: error while executing at wasm backtrace:
0: 0x2be2 - vfprintf
at /wasi-libc/libc-top-half/musl/src/stdio/vfprintf.c:726:3
1: 0x2db - printf
at /wasi-libc/libc-top-half/musl/src/stdio/printf.c:9:8
2: 0x265 - <unknown>!process_string
3: 0xb965 - <unknown>!process_string.command_export
4: 0x44d - <unknown>!main
5: 0xcd49 - <unknown>!__main_void
6: 0x39c - _start
at /wasi-libc/libc-bottom-half/crt/crt1-command.c:43:13
2: wasm trap: undefined element: out of bounds table access
I think both module are loaded, but seems like something is going wrong with function pointers (or function table) in a multi-module setup. Can you help me understand what might be causing this error?
Last updated: Jan 24 2025 at 00:11 UTC