Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling an exported function causes a panic #265

Closed
MindSwipe opened this issue Jul 6, 2023 · 3 comments · Fixed by bytecodealliance/wasmtime#6745
Closed

Calling an exported function causes a panic #265

MindSwipe opened this issue Jul 6, 2023 · 3 comments · Fixed by bytecodealliance/wasmtime#6745

Comments

@MindSwipe
Copy link

I'm trying to compile C# to WASM and then execute that WASM using wasmtime-dotnet but for some reason it panics when trying to invoke the method. Here's the C# code that gets compiled to WASM:

public class Program
{
    public static unsafe void SayHello()
    {
        System.Console.WriteLine("Hello World!");
    }
}

Using some native C to actually get the SayHello method to be exported as __say_hello (I got it to work using this issue on the dotnet-wasi-sdk repo), here is that C:

MonoMethod* method_HandleGuestCall;
MonoObject* interop_instance = 0;

__attribute__((export_name("__say_hello")))
void __say_hello() {
    if (!method_HandleGuestCall) {
        method_HandleGuestCall = lookup_dotnet_method("LimeLead.Core.dll", "LimeLead.Core", "Program", "SayHello", -1);
        assert(method_HandleGuestCall);
    }

    MonoObject *exception;
    mono_wasm_invoke_method(method_HandleGuestCall, NULL, NULL, &exception);
    assert(!exception);
}

I'm then using the following code to try and invoke the __say_hello method:

using var engine = new Engine();
using var linker = new Linker(engine);
using var store = new Store(engine);

linker.DefineWasi();

using var csharpModule = Module.FromFile("myWasm.wasm");
var csharpInstance = linker.Instantiate(store, csharpModule);
var sayHello = csharpInstance.GetAction("__say_hello");
sayHello();

This fails with the exception being SEHException (0x80004005): External component has thrown an exception. and the console window shows the following before the stacktrace:

thread '' panicked at 'called Option::unwrap() on a None value', crates\c-api\src\linker.rs:105:80
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace.

Calling the function directly with the wasmtime cli using wasmtime --invoke __say_hello .\myWasm.wasm results in the following error:

* Assertion at /home/runner/work/dotnet-wasi-sdk/dotnet-wasi-sdk/modules/runtime/src/mono/mono/metadata/assembly-load-context.c:81, condition `default_alc' not met

Error: failed to run main module `.\myWasm.wasm`

Caused by:
    0: failed to invoke `__say_hello`
    1: wasm trap: wasm `unreachable` instruction executed
       wasm backtrace:
           0: 0x4041fc - <unknown>!<wasm function 7608>
           1: 0x3f579e - <unknown>!<wasm function 7285>
           2: 0x3f6222 - <unknown>!<wasm function 7300>
           3: 0x3f5ed5 - <unknown>!<wasm function 7295>
           4: 0x3f5d81 - <unknown>!<wasm function 7293>
           5: 0x3f5fc9 - <unknown>!<wasm function 7297>
           6: 0x3f6054 - <unknown>!<wasm function 7298>
           7: 0x29f796 - <unknown>!<wasm function 4242>
           8: 0xf9967 - <unknown>!<wasm function 915>
           9: 0xe1ecb - <unknown>!<wasm function 701>
          10: 0xe28a2 - <unknown>!<wasm function 708>
          11: 0x3381 - <unknown>!<wasm function 36>
          12: 0x41790f - <unknown>!<wasm function 7892>

I now found this issue on the ASP.NET Core repo where another user had the same condition default_alc' not met, their fix is calling _startbefore anything else, this sadly does not fix my problem as calling_startfrom C# fails withSEHException (0x80004005): External component has thrown an exception.and Rustthread '' panicked at 'called Option::unwrap() on a None value', crates\c-api\src\linker.rs:105:80`, however it does work when calling it directly using the wasmtime cli.

@MindSwipe
Copy link
Author

Hmm, I got it to work by switching over my C# project which gets compiled to WASM to be an Exe instead of a Library, as well as removing the linker.DefineWasi() line and stubbing out the WASI methods as described here

@peterhuene
Copy link
Member

peterhuene commented Jul 6, 2023

You're missing a call to store.SetWasiConfiguration(new WasiConfiguration()); (if the default configuration is acceptable) to configure WASI on the store.

Unfortunately the Wasmtime internals underlying Linker.DefineWasi will panic if the store has no WASI configuration at instantiation time.

There's no good way for us to improve this experience from the .NET side of things as the callback mechanism by which the linker extracts the WASI configuration from the store is internal to the Wasmtime API and it is expected to panic if the API isn't used properly.

@peterhuene
Copy link
Member

At a bare minimum, we could at least change the unwrap call in the Wasmtime API to an expect explaining that a WASI configuration was not set in the store.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants