Skip to content

Missing frame in trap message. #1845

Closed
Closed

Description

@peterhuene

In the .NET repo, there's a test (see corresponding .wat file here) that defines a host function that throws a .NET exception. The .NET API turns the exception into a C API wasm_trap_t.

This results in the following trap message on Windows:

Test error message for wasmtime dotnet unit tests.
wasm backtrace:
  0:   0xad - <unknown>!do_throw

However, on Linux and macOS, the Wasm frame is missing:

Test error message for wasmtime dotnet unit tests.

We should be able to properly capture the backtrace across all platforms and translate the wasm frames.

See bytecodealliance/wasmtime-dotnet#16 for an example of the failure (ignore the general I/O error encountered: Invalid argument (os error 22) failures as that's fixed by a Wasmtime PR under review).

cc @alexcrichton @yurydelendik

Activity

  1. added
    bugIncorrect behavior in the current implementation that needs fixing
    on Jun 8, 2020
  2. peterhuene commented on Jun 8, 2020

    @peterhuene
    MemberAuthor

    Note: I haven't investigated this at all, just noticed the discrepancy and filed the issue.

  3. self-assigned this
    on Jun 8, 2020
  4. alexcrichton commented on Jun 9, 2020

    @alexcrichton
    Member

    Hm so my guess here is that the backtrace crate probably couldn't backtrace through .NET frames. Can you try confirming that with println!("{:?}", Backtrace::new()) inside of wasm_trap_new?

  5. peterhuene commented on Jun 10, 2020

    @peterhuene
    MemberAuthor

    That would make sense. Unfortunately the CLR doesn't register JIT frames with libunwind, so I think we're probably out of luck here.

    An incomplete fix would be to replace an empty trace for a trap returned from invoking a wasm_func_callback_t in func.rs, which would at least provide Wasm frames until the next CLR frame is encountered on the stack.

    This quick hack does produce the expected result since there are no other .NET frames between any of the Wasm frames for this particular test case:

    if let Some(trap) = out {
        let trap = trap.trap.borrow();
        if trap.trace().is_empty() {
            return Err(Trap::new(trap.to_string()));
        }
        return Err(trap.clone());
    }
  6. alexcrichton commented on Jun 10, 2020

    @alexcrichton
    Member

    That actually seems somewhat reasonable to me, it may be the case that libbacktrace can't backtrace through a number of native runtimes so having this may not be the worst thing in the world. Especially since we primarily want wasm stack frames the Rust code is guaranteed to see the same wasm frames that the CLR would have seen otherwise.

  7. peterhuene commented on Apr 15, 2026

    @peterhuene
    MemberAuthor

    Closing this old issue as I am auditing my assigned issues.

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

Metadata

Metadata

Assignees

Labels

bugIncorrect behavior in the current implementation that needs fixing

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions