bytecodealliance / wasm-micro-runtime

WebAssembly Micro Runtime (WAMR)
Apache License 2.0
4.93k stars 624 forks source link

AOT module load failed #629

Open loloRvz opened 3 years ago

loloRvz commented 3 years ago

I am currently trying to write a program which can load and execute functions from AoT compiled wasm module using the wasm-c-api. Keeping the wasm modules and their functions simple (e.g int sum(int a,intb){return a+b;} ) my program works perfectly. It's when I do callbacks or use stdlib (eg. printf) that I get the following errors respectively when compiling the module:

For context: I am not running it on Linux, but rather on a SabreLITE 6quad board (armv7a arch) running NuttX. The program is a custom NuttX app I'm writing in C. I pass the precompiled wasm modules (.aot) to my development board and then run the program. I tested this program on my machine using Linux already and it works perfectly.

I realise this is confusing and I am not doing a great job explaining my problem, here's my procedure:

I wrote my wasm module in C (module.c):

int sum(int a, int b){
    return a+b;
}

__attribute__((import_name("callfunc"))) void call(void);
void callcallback(){
    call();
}

I convert it to wasm and then precompile it with wamrc targeting the correct architecture:

/opt/wasi-sdk/bin/clang \
    -o module.wasm module.c \
    -O3 -z stack-size=8192 -nostdlib \
    -Wl,--initial-memory=65536 \
    -Wl,--strip-all,--no-entry \
    -Wl,--export=sum \
    -Wl,--export=callcallback \
    -Wl,--import-memory 

wamrc --target=thumbv7a \
      --cpu=cortex-a9 \
      -o mod.aot module.wasm

I then pass mod.aot to my developement board and run the following app:

own wasm_trap_t* callback_func(const wasm_val_t args[], wasm_val_t results[]){
    printf("Running callback function...\n");
    return NULL;
}

int main(int argc, char *argv[]){

    if(argc != 2){
        printf("> Error incorrect input!\nUsage: nsh> wafle <aot_file>\n"); 
        return 1;
    }

    //Initialise
    printf("Initialising...\n");
    wasm_engine_t* engine = wasm_engine_new_with_args(Alloc_With_System_Allocator,NULL,2);
    //wasm_engine_t* engine = wasm_engine_new();
    wasm_store_t* store = wasm_store_new(engine);

    //Load binary
    printf("Loading binary...\n");
    FILE* file = fopen(argv[1], "rb");
    if (!file) {
      printf("> Error opening module!\n"); return 1;
    }
    fseek(file, 0L, SEEK_END);
    size_t file_size = ftell(file);
    fseek(file, 0L, SEEK_SET);
    wasm_byte_vec_t binary;
    wasm_byte_vec_new_uninitialized(&binary, file_size);
    if (fread(binary.data, file_size, 1, file) != 1) {
      printf("> Error loading module!\n"); return 1;
    }
    fclose(file);

        ***** FAILS HERE ******

    //Compile module
    printf("Compiling module...\n");
    own wasm_module_t* module = wasm_module_new(store, &binary); //Fails here
    if (!module) {
        printf("> Error compiling module!\n"); return 1;
    }
    wasm_byte_vec_delete(&binary);

    // Create external print functions.
    printf("Creating callback...\n");
    own wasm_functype_t* call_type = wasm_functype_new_0_0();
    own wasm_func_t* callfunc = wasm_func_new(store,call_type,callback_func);
    wasm_functype_delete(call_type);

    // Instantiate.
    printf("Instantiating module...\n");
    const wasm_extern_t* imports[] = { wasm_func_as_extern(callfunc) };
    own wasm_instance_t* instance =
        wasm_instance_new(store, module, imports, NULL);
    if (!instance) {
        printf("> Error instantiating module!\n"); return 1;
    }

    //Extract eports
    printf("Extracting export...\n");
    own wasm_extern_vec_t exports;
    wasm_instance_exports(instance, &exports);
    if (exports.size == 0) {
        printf("> Error accessing exports!\n"); return 1;
    }
    const wasm_func_t* sum_wasmfunc = wasm_extern_as_func(exports.data[0]);
    if (sum_wasmfunc == NULL) {
        printf("> Error accessing export!\n"); return 1;
    }
    const wasm_func_t* call_wasmfunc = wasm_extern_as_func(exports.data[0]);
    if (call_wasmfunc == NULL) {
        printf("> Error accessing export!\n");return 1;
    }
    //Delete module
    wasm_module_delete(module);
    wasm_instance_delete(instance);

    //Call exports
    printf("Calling export...\n");
    wasm_val_t args[2];
    args[0].kind = WASM_I32;
    args[0].of.i32 = 6;
    args[1].kind = WASM_I32;
    args[1].of.i32 = 9;
    wasm_val_t results[1];
    if (wasm_func_call(sum_wasmfunc, args, results)) {
        printf("> Error calling function!\n"); return 1;
    }
    printf("Printing result...\n");
    printf("> %u\n", results[0].of.i32);

    if (wasm_func_call(call_wasmfunc, NULL, NULL)) {
        printf("> Error calling function!\n"); return 1;
    }
    wasm_extern_vec_delete(&exports);

    //Shut down
    printf("Shutting down...\n");
    wasm_store_delete(store);
    wasm_engine_delete(engine);

}

I tried debugging this issue for a week now and have gotten nowhere, since gdb doesn't work well with NuttX. Does anybody might know what might cause this problem?

lum1n0us commented 3 years ago

would you mind sharing both .wasm file?

loloRvz commented 3 years ago

In this case there's just one wasm file which includes two functions, sum() and callcallback(). Here is the module written in c, converted to .wasm and compiled to .aot

module.tar.gz

lum1n0us commented 3 years ago

would you mind trying with iwasm likes, and past the output here

$ somewhere/iwasm mod.aot