Skip to content

Exception: "wasm trap: uninitialized element" #97

Closed

Description

@ignatz

I'm successfully building a WASM component:

using System.Text;

namespace TrailbaseWorld.wit.exports.trailbase.runtime
{
    public class InitEndpointImpl : IInitEndpoint
    {
        public static IInitEndpoint.InitResult Init()
        {
            throw new Exception("test");
            return new IInitEndpoint.InitResult(httpHandlers: [], jobHandlers: []);
        }
    }
}

namespace ProxyWorld.wit.exports.wasi.http.v0_2_0
{
    using ProxyWorld.wit.imports.wasi.http.v0_2_0;

    public class IncomingHandlerImpl : IIncomingHandler
    {
        public static void Handle(ITypes.IncomingRequest request, ITypes.ResponseOutparam responseOut)
        {
           // ...
        }
    }
}
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Library</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>

    <RuntimeIdentifier>wasi-wasm</RuntimeIdentifier>
    <UseAppHost>false</UseAppHost>
    <PublishTrimmed>true</PublishTrimmed>
    <InvariantGlobalization>true</InvariantGlobalization>
    <SelfContained>true</SelfContained>

    <!-- <IlcExportUnmanagedEntrypoints>true</IlcExportUnmanagedEntrypoints> -->
  </PropertyGroup>

  <ItemGroup>
    <!-- <PackageReference Update="Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-preview.2.25220.1" /> -->
    <PackageReference Include="BytecodeAlliance.Componentize.DotNet.Wasm.SDK" Version="0.7.0-preview00010" />
    <PackageReference Include="runtime.$(NETCoreSdkPortableRuntimeIdentifier).microsoft.dotnet.ilcompiler.llvm" Version="10.0.0-preview.2.25220.1" />
  </ItemGroup>

  <ItemGroup>
    <Wit Include="wit/http.wasm" World="proxy" Registry="ghcr.io/webassembly/wasi/http:0.2.0" />
  </ItemGroup>
</Project>

However, when I call my InitEndpoint, i'm getting the following exception:

Err(Wasmtime(error while executing at wasm backtrace:
    0: 0x52d47f - S_P_CoreLib_System_Runtime_EH__DispatchException
                    at /_/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.wasm.cs:68:0
    1: 0x43f5dd - S_P_CoreLib_System_Runtime_EH__RhpThrowEx
                    at /_/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.wasm.cs:39:0
    2: 0x2d91ac - S_P_CoreLib_Internal_Runtime_CompilerHelpers_ThrowHelpers__ThrowNullReferenceException
                    at /_/src/libraries/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/ThrowHelpers.cs:20:0
    3: 0x2d9403 - S_P_CoreLib_Internal_Runtime_CompilerHelpers_StartupCodeHelpers__InitializeGlobalTablesForModule
                    at /_/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs:128:0
    4:  0x3f4d5 - S_P_CoreLib_Internal_Runtime_CompilerHelpers_StartupCodeHelpers__InitializeModules
                    at /_/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs:39:0
    5:   0x4d94 - .tmpzokCgm!InitializeRuntime()
    6:   0x87b8 - .tmpzokCgm!Thread::ReversePInvokeAttachOrTrapThread(ReversePInvokeFrame*)
    7:   0x88c4 - .tmpzokCgm!RhpReversePInvokeAttachOrTrapThread2
    8:  0x3e663 - .tmpzokCgm!RhpReversePInvoke
    9: 0x2168fe - Guest_TrailbaseWorld_wit_exports_trailbase_runtime_InitEndpointInterop__wasmExportInit
                    at /home/sebastian/projects/trailbase/guests/dotnet/obj/Debug/net10.0/wasi-wasm/wit_bindgen/TrailbaseWorld.wit.exports.trailbase.runtime.InitEndpointInterop.cs:13:0

Caused by:
    wasm trap: uninitialized element

When looking at the generated referenced code TrailbaseWorld.wit.exports.trailbase.runtime.InitEndpointInterop.cs:13:, in obj/Release/net10.0/wasi-wasm/wit_bindgen/TrailbaseWorld.wit.exports.trailbase.runtime.InitEndpointInterop.cs, it looks pretty innocent:

// Generated by `wit-bindgen` 0.41.0. DO NOT EDIT!
// <auto-generated />
#nullable enable

using System.Text;
using System.Runtime.InteropServices;

namespace TrailbaseWorld.wit.exports.trailbase.runtime
{
    public static class InitEndpointInterop {

        [UnmanagedCallersOnly(EntryPoint = "trailbase:runtime/init-endpoint#init")]
        public static unsafe nint wasmExportInit() {

            global::TrailbaseWorld.wit.exports.trailbase.runtime.IInitEndpoint.InitResult ret;
            ret = InitEndpointImpl.Init();

            var ptr = InteropReturnArea.returnArea.AddressOfReturnArea();

            var bufferSize = 12 * (nuint)ret.httpHandlers.Count;
            void* address = NativeMemory.AlignedAlloc(bufferSize, 4);

// ...

In fact, the C# exception seems to be thrown when calling my implementation of IInitEndpoint.Init() but before exercising the implementation itself.

I'm getting the same result for Debug and Release builds. I also couldn't find anyone else experiencing the same issue. Also FWIW, the same host runtime works for WASM components built with rust or JS.

Any thoughts on what I'm doing wrong? Wanted to ask before building a more elaborate reproduction.

Thanks 🙏

Activity

  1. jsturtevant commented on Sep 15, 2025

    @jsturtevant
    Contributor

    Is this exception in your code expected?

         public static IInitEndpoint.InitResult Init()
            {
                throw new Exception("test");
    

    I am seeing 2: 0x2d91ac - S_P_CoreLib_Internal_Runtime_CompilerHelpers_ThrowHelpers__ThrowNullReferenceException maybe a simple reproduction might help here.

  2. ignatz commented on Sep 15, 2025

    @ignatz
    Author

    Is this exception in your code expected?

         public static IInitEndpoint.InitResult Init()
            {
                throw new Exception("test");
    

    I am seeing 2: 0x2d91ac - S_P_CoreLib_Internal_Runtime_CompilerHelpers_ThrowHelpers__ThrowNullReferenceException maybe a simple reproduction might help here.

    I would love my exception to trigger. It doesn't.

    I can set something up. The component fails before my code is reached.

  3. ignatz commented on Sep 15, 2025

    @ignatz
    Author

    Thanks for your time and effort 🙏

    Repro (requires installed Rust toolchain).

    git clone https://github.com/trailbaseio/trailbase.git
    cd trailbase
    git checkout dotnet-guest
    cargo run --bin repro -- guests/dotnet/bin/Release/net10.0/wasi-wasm/native/Guest.wasm 

    which should eventually produce:

    ...
    Initializing component: "guests/dotnet/bin/Release/net10.0/wasi-wasm/native/Guest.wasm"
    Ok(Err(Wasmtime(error while executing at wasm backtrace:
        0:  0xa3d6e - .tmpvYOFJ0!S_P_CoreLib_System_Runtime_EH__DispatchException
        1:  0x6293b - .tmpvYOFJ0!S_P_CoreLib_System_Runtime_EH__RhpThrowEx
        2:  0x827c6 - .tmpvYOFJ0!S_P_CoreLib_Internal_Runtime_CompilerHelpers_ThrowHelpers__ThrowNullReferenceException
        3:  0x7952c - .tmpvYOFJ0!S_P_CoreLib_Internal_Runtime_CompilerHelpers_StartupCodeHelpers__InitializeGlobalTablesForModule
        4:  0xbde43 - .tmpvYOFJ0!S_P_CoreLib_Internal_Runtime_CompilerHelpers_StartupCodeHelpers__InitializeModules
        5:   0x3942 - .tmpvYOFJ0!InitializeRuntime()
        6:   0x72c6 - .tmpvYOFJ0!Thread::ReversePInvokeAttachOrTrapThread(ReversePInvokeFrame*)
        7:   0x73d2 - .tmpvYOFJ0!RhpReversePInvokeAttachOrTrapThread2
        8:  0x3bf14 - .tmpvYOFJ0!RhpReversePInvoke
        9:  0x82d0b - .tmpvYOFJ0!Guest_TrailbaseWorld_wit_exports_trailbase_runtime_InitEndpointInterop__wasmExportInit
    note: using the `WASMTIME_BACKTRACE_DETAILS=1` environment variable may show more debugging information
    
    Caused by:
        wasm trap: uninitialized element)))
    

    for the PoC dotnet component living in guests/dotnet.

    For reference, doing the same with a Rust component:

    cargo run --bin repro -- client/testfixture/wasm/wasm_rust_guest_testfixture.wasm                                                                    ~/projects/trailbase
        Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.62s
         Running `target/debug/repro client/testfixture/wasm/wasm_rust_guest_testfixture.wasm`
    Initializing component: "client/testfixture/wasm/wasm_rust_guest_testfixture.wasm"
    Ok(Ok(InitResult { http-handlers: [(MethodType::Get, "/readfile"), (MethodType::Get, "/json"), (MethodType::Get, "/fetch"), (MethodType::Get, "/error"), (MethodType::Get, "/await"), (MethodType::Get, "/addDeletePost"), (MethodType::Get, "/transaction"), (MethodType::Get, "/fibonacci")], job-handlers: [("WASM-registered Job", "@hourly")] }))
    

    JavaScript components work as well.

    I would love to help. Let me know if there's anything else I can do 🙏

  4. yowl commented on Sep 16, 2025

    @yowl
    Contributor

    From the first stack in the OP, it looks like the TypeManagerIndirection section is missing or can't be found causing the dotnet runtime initialisation to fail.

  5. ignatz commented on Sep 16, 2025

    @ignatz
    Author

    From the first stack in the OP, it looks like the TypeManagerIndirection section is missing or can't be found causing the dotnet runtime initialisation to fail.

    👍 is there something I'm doing wrong or something I should be doing differently?

  6. GerardSmit commented on Sep 16, 2025

    @GerardSmit
    Contributor

    This happens when Microsoft.DotNet.ILCompiler.LLVM and runtime.X.Microsoft.DotNet.ILCompiler.LLVM versions are mismatching.

    You're updating the runtime in the Guest.csproj here to 10.0.0-preview.2.25220.1:
    https://github.com/trailbaseio/trailbase/blob/079b382ded8cfc6b71ad83399371fcd52afa5262/guests/dotnet/Guest.csproj#L21

    But the SDK isn't updated, and is still coming from componentize-dotnet. Which is 10.0.0-alpha.1.25162.1:

    <PackageVersion Include="Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-alpha.1.25162.1" />

    If I'm correct, you can update the LLVM version with:

    <PackageVersion Update="Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-preview.2.25220.1" /> 
    <PackageVersion Include="runtime.$(NETCoreSdkPortableRuntimeIdentifier).microsoft.dotnet.ilcompiler.llvm" Version="10.0.0-preview.2.25220.1" /> 

    Or revert the version to 10.0.0-alpha.1.25162.1, since this one is tested 🙂

  7. ignatz commented on Sep 16, 2025

    @ignatz
    Author

    @GerardSmit 🙏

    If I'm correct, you can update the LLVM version with:

    FTR: I couldn't get this to work. I threw various combinations of

        <PackageReference Update="Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-preview.2.25220.1" /> 
        <PackageVersion Update="Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-preview.2.25220.1" /> 
        <PackageReference Include="runtime.$(NETCoreSdkPortableRuntimeIdentifier).microsoft.dotnet.ilcompiler.llvm" Version="10.0.0-preview.2.25220.1" />
    

    Into my project manifest but I continued to get the same error. Hopefully, I'm just clumsy, otherwise this may be something you'll encounter when updating 🤷‍♀️

    Or revert the version to 10.0.0-alpha.1.25162.1, since this one is tested 🙂

    This worked! 🙏

    Not familiar enough with dotnet to suggest anything but maybe there's a way to enforce downstream packages using a consistent version with the upstream BytecodeAlliance.Componentize.DotNet.Wasm.SDK? 🤷‍♀️

    Thanks again

  8. GerardSmit commented on Sep 16, 2025

    @GerardSmit
    Contributor

    Into my project manifest but I continued to get the same error.

    Huh, that's weird. I have the following in my .csproj which works:

    <ItemGroup>
        <PackageReference Update="Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-alpha.1.25162.1"/>
        <PackageReference Include="runtime.win-x64.microsoft.dotnet.ilcompiler.llvm" Version="10.0.0-alpha.1.25162.1"/>
        <PackageReference Include="BytecodeAlliance.Componentize.DotNet.Wasm.SDK" Version="0.7.0-preview00010"/>
    </ItemGroup>

    Edit: I just saw this is the alpha version. I'm not sure what I did previously to make it work. 😅

    Not familiar enough with dotnet to suggest anything but maybe there's a way to enforce downstream packages using a consistent version with the upstream BytecodeAlliance.Componentize.DotNet.Wasm.SDK? 🤷‍♀️

    That would be better, yes. I'm not sure why the runtime is in the template (outside of the Componentize SDK).

  9. jsturtevant commented on Sep 16, 2025

    @jsturtevant
    Contributor

    That would be better, yes. I'm not sure why the runtime is in the template (outside of the Componentize SDK).

    This has been consistent issue getting the correct package for the RID. I tried fixing it a few different times and using a template has been the least painful. See #54 (comment)

    if you have an ideas on making this better let me know

  10. GerardSmit commented on Sep 16, 2025

    @GerardSmit
    Contributor

    I see what you mean.

    if you have an ideas on making this better let me know

    The only thing I can come up with, it making a project SDK, but this changes how you consume the NuGet package:

    + <Project Sdk="BytecodeAlliance.Componentize.DotNet.Wasm.SDK/[VERSION]">
      
        <PropertyGroup>
          <OutputType>Exe</OutputType>
          <TargetFramework>net10.0</TargetFramework>
          <RootNamespace>wasi_cli</RootNamespace>
          <ImplicitUsings>enable</ImplicitUsings>
          <Nullable>enable</Nullable>
          <InvariantGlobalization>true</InvariantGlobalization>
        </PropertyGroup>
    
    - <ItemGroup>
    -   <PackageReference Include="BytecodeAlliance.Componentize.DotNet.Wasm.SDK" Version="0.7.0-preview*" />
    -   <PackageReference Include="runtime.$(NETCoreSdkPortableRuntimeIdentifier).microsoft.dotnet.ilcompiler.llvm" Version="10.0.0-alpha.1.25162.1" />
    - </ItemGroup>
    
      </Project>

    I've created a draft PR: #99.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions