bytecodealliance / wasmtime

A fast and secure runtime for WebAssembly
https://wasmtime.dev/
Apache License 2.0
15.41k stars 1.3k forks source link

Improve error messages #9293

Open SoniEx2 opened 1 month ago

SoniEx2 commented 1 month ago

Feature

Improve error messages.

Benefit

Descriptive error messages are useful when writing raw wasm code.

Implementation

N/A

Alternatives

Not much of an alternative, but one can use wabt. For comparison, wasmtime:

$ wasmtime stack-types.wat 
Error: WebAssembly translation error

Caused by:
    Invalid input WebAssembly code at offset 45: type mismatch: expected i32 but nothing on stack

wabt:

$ wat2wasm stack-types.wat 
stack-types.wat:3:5: error: type mismatch in i32.eqz, expected [i32] but got []
    i32.eqz
    ^^^^^^^
cfallin commented 1 month ago

@SoniEx2 could you clarify which part you'd like to be improved? The type mismatch itself is roughly the same in both ("expected i32" vs. "expected [i32]", "nothing on stack" vs. "got []", I'd argue wasmtime's "nothing on stack" is even a little bit better here). Is it the location/context, i.e. offset 45 vs. ....wat:3.5? That I believe is an artifact of translating from wat to binary before validating; perhaps we could thread through original source locations, but that's a slightly nontrivial refactor.

SoniEx2 commented 1 month ago

Arguably wasmtime's "nothing on stack" is a little better, and we should maybe improve that in wabt. But between the lack of line numbers and the lack of spans, in actual use, wasmtime is so much worse...

And this is only one example. We haven't gone around trying to find all cases where wasmtime has worse error messages.

alexcrichton commented 1 month ago

The best error messages are probably not going to come from either Wasmtime or wasm-tools and the underlying tools. Architecturally most tooling assumes the input is a wasm binary and converts text-to-binary primarily as a convenience. This differs from wabt, I believe, which stores the AST of the program which provides a much richer understanding of the original text when the text is input. In Wasmtime (and wasm-tools) the textual AST and such are all lost quickly during the text-to-binary transformation.

In https://github.com/bytecodealliance/wasm-tools/pull/1632 I implemented rudimentary support for metadata in the wasm module which can point back to the original source. This support is turned off by default in the text-to-binary transform. For example though:

$ cat foo.wat
(module
  (func
    i32.eqz)
)
$ wasm-tools validate foo.wat
error: func 0 failed to validate

Caused by:
    0: type mismatch: expected i32 but nothing on stack (at offset 0x17)
$ wasm-tools validate -g foo.wat
error: ./foo.wat:3:5 function `wasm-function[0]` failed to validate

Caused by:
    0: func 0 failed to validate
    1: type mismatch: expected i32 but nothing on stack (at offset 0x17)

Here the -g flag is injecting dwarf debugging information which the error rendering then takes into account to print out a filename and a line number. Wasmtime does not implement this logic yet, though.

In the end though even with DWARF support the tooling only supports filenames/line numbers in the code section, nowhere else in the module. Given that you'd probably still get higher fidelity error messages from a tool like wabt which maintains the original text AST and spans.

SoniEx2 commented 1 month ago

here's something that would help a lot, and we don't have an equivalent to compare it to: when a component import fails, print the expected and real types