vouillon added the bug label to Issue #10181.
vouillon opened issue #10181:
Test Case
Steps to Reproduce
Run the following command:
./target/debug/wasmtime -W=all-proposals=y constprop.wasmExpected Results
This works fine if one add the
-C collector=nulloption:$ ./target/debug/wasmtime -C collector=null -W=all-proposals=y constprop.wasm booleans: passed integers: passed floats: passed 32-bit integers: passed native integers: passed 64-bit integers: passed integer conversions: passed 32-bit integer conversions: passed native integer conversions: passed 64-bit integer conversions: passedActual Results
This crashes with an
Illegal instructionerror.Versions and Environment
Wasmtime commit: 0e0560087beff704bc111a1abb1d6a80c1b5da70
Operating system: Linux
Architecture: x64
alexcrichton assigned afonso360 to issue #10181.
alexcrichton assigned fitzgen to issue #10181.
alexcrichton unassigned afonso360 from issue #10181.
fitzgen commented on issue #10181:
Thanks for the bug report!
If you have time, minimizing the test case
watwithcreducewould be very appreciated and make diagnosing and fixing this easier. If not, I'll get around to that eventually.
fitzgen added the wasm-proposal:gc label to Issue #10181.
just-an-engineer commented on issue #10181:
I'll take this.
After some initial looking, it has to do with the async stuff, I'm guessing it pops the wrong address somehow.
just-an-engineer commented on issue #10181:
Where is this wasm file from, and how did you compile it?
I suspect it may be from an invalid wasm file, which the code _should_ check for currently, but doesn't seem to. Runningwasm-validateon it gives me an error of invalid type a few bytes in, but I imagine that tools stops after the first error, so no idea how many more.
Anyways, it could be that there's some invalid stuff here that operates outside of the specification, that leds to an incorrect address being jumped to during the async execution stuffs.
vouillon commented on issue #10181:
This code relies on the Wasm GC proposal. This proposal is not supported by
wasm-validate. That's why you get errors.
The code is generated using wasm_of_ocaml, which compiles OCaml code to Wam.
The source code comes from the OCaml test suite, so it is a bit weird.
wasm-optfrom the binaryen toolchain is used to optimize the code. And the code runs fine innode. So I'm quite confident regarding its validity.
fitzgen commented on issue #10181:
@just-an-engineer
I'll take this.
You're definitely welcome to investigate this bug, but this isn't likely the best good-first-issue kind of bug if you aren't already somewhat familiar with Wasmtime and Cranelift.
What would be super helpful whether you continue to investigate this bug or leave it for someone else would be to run
creduceon the.watdisassembly of the test case and reduce it to a minimal example that triggers the illegal instruction fault. This would involve something like:
wasm-tools wasm2wat test.wasm -o test.watWriting a
predicate.shthat does something like
sh #!/usr/bin/env bash set -eu cargo run --manifest-path ~/path/to/wasmtime/Cargo.toml -- \ -C collector=null -W=all-proposals=y \ test.wat \ 2>&1 | grep -q 'Illegal instruction'
(Note: the above is untested, you would want to make sure that it exits1iftest.wasmdoesn't trigger the illegal instruction and0if it does trigger the illegal instruction.)And finally run
creducesomething like
creduce --not-c predicate.sh test.watAnd when
creduceis finished, post the reduced test case here.I suspect it may be from an invalid wasm file
Wasmtime always validates the Wasm as part of its process of translating it to Cranelift's IR (called CLIF) so, barring validator bugs, we should never actually execute any invalid Wasm file.
vouillon commented on issue #10181:
I have used
wasm-reduce(from the Binaryen toolchain) andcreduce, plus some manual rewriting, to reduce the size of the code. It remains a bit large, probably because one needs a specific allocation pattern to trigger the bug. In particular, there is a global array which is not used anywhere, and some values that are dropped right after being allocated.
A circular datastructure is built usingstruct.set. Maybe this confuses the GC? I don't see anything else suspicious.
constprop.wat.txt
tanishiking commented on issue #10181:
We encountered an "Illegal Instruction" error in our project (scala-wasm fork of Scala.js to support wasm component model).
I'm not sure if this is the only case, but the error occurs at least when we try to set an
i31value (converted from i32 with the MSB has 1) to ananyrefstruct field.(module (type $c.scala.Tuple1 (sub (struct (field $f.scala.Tuple1._1 (mut anyref))))) (func (export "test") (local $instance (ref $c.scala.Tuple1)) i32.const -2 ref.i31 struct.new $c.scala.Tuple1 drop ) )$ wasm-tools parse test.wat -o test.wasm $ wasmtime run -W function-references,gc --invoke test test.wasm make: *** [run] Illegal instruction: 4see: https://github.com/tanishiking/kitchensink/tree/main/wasmtime-illegal-instruction
As @vouillon mentioned, the problem doesn't happen when using the
-C collector=nulloption.$ wasmtime --version wasmtime 29.0.1 (58282df89 2025-01-21)
tanishiking edited a comment on issue #10181:
We encountered an "Illegal Instruction" error in our project (scala-wasm fork of Scala.js to support wasm component model).
I'm not sure if this is the only case, but the error occurs at least when we try to set an
i31value (converted from i32 with the MSB has 1) to ananyrefstruct field.(module (type $c.scala.Tuple1 (sub (struct (field $f.scala.Tuple1._1 (mut anyref))))) (func (export "test") (local $instance (ref $c.scala.Tuple1)) i32.const -2 ref.i31 struct.new $c.scala.Tuple1 drop ) )$ wasm-tools parse test.wat -o test.wasm $ wasmtime run -W function-references,gc --invoke test test.wasm make: *** [run] Illegal instruction: 4see: https://github.com/tanishiking/kitchensink/tree/main/wasmtime-illegal-instruction
- As @vouillon mentioned, the problem doesn't happen when using the
-C collector=nulloption.- I guess there're other reproductions as well, because I find there's only
(ref.i31 (i32.const 0))in @vouillon 's reproduction case.$ wasmtime --version wasmtime 29.0.1 (58282df89 2025-01-21)
tanishiking edited a comment on issue #10181:
We encountered an "Illegal Instruction" error in our project (scala-wasm fork of Scala.js to support wasm component model).
I'm not sure if this is the only case, but the error occurs at least when we try to set an
i31value (converted from i32 with the MSB has 1) to ananyrefstruct field.(module (type $c.scala.Tuple1 (sub (struct (field $f.scala.Tuple1._1 (mut anyref))))) (func (export "test") (local $instance (ref $c.scala.Tuple1)) i32.const -1 ref.i31 struct.new $c.scala.Tuple1 drop ) )$ wasm-tools parse test.wat -o test.wasm $ wasmtime run -W function-references,gc --invoke test test.wasm make: *** [run] Illegal instruction: 4see: https://github.com/tanishiking/kitchensink/tree/main/wasmtime-illegal-instruction
- As @vouillon mentioned, the problem doesn't happen when using the
-C collector=nulloption.- I guess there're other reproductions as well, because I find there's only
(ref.i31 (i32.const 0))in @vouillon 's reproduction case.$ wasmtime --version wasmtime 29.0.1 (58282df89 2025-01-21)
tanishiking edited a comment on issue #10181:
We encountered an "Illegal Instruction" error in our project (scala-wasm fork of Scala.js to support wasm component model).
The error occurs at least when we try to set an
i31value (converted from i32 with the MSB has 1) to ananyrefstruct field.(module (type $c.scala.Tuple1 (sub (struct (field $f.scala.Tuple1._1 (mut anyref))))) (func (export "test") (local $instance (ref $c.scala.Tuple1)) i32.const -1 ref.i31 struct.new $c.scala.Tuple1 drop ) )$ wasm-tools parse test.wat -o test.wasm $ wasmtime run -W function-references,gc --invoke test test.wasm make: *** [run] Illegal instruction: 4see: https://github.com/tanishiking/kitchensink/tree/main/wasmtime-illegal-instruction
- As @vouillon mentioned, the problem doesn't happen when using the
-C collector=nulloption.- I guess there're other reproductions as well, because I find there's only
(ref.i31 (i32.const 0))in @vouillon 's reproduction case.$ wasmtime --version wasmtime 29.0.1 (58282df89 2025-01-21)
tanishiking commented on issue #10181:
This particular example https://github.com/bytecodealliance/wasmtime/issues/10181#issuecomment-2665004815 has fixed in local-built wasmtime (287e8fb5405a943f67babf08643e23bea449e7bf) :tada: thanks! maybe https://github.com/bytecodealliance/wasmtime/pull/10091 was the fix?
but we still hit the
Illegal instruction: 4error in larger binary, I'll share it when I could make a bit smaller reproducible example.
tanishiking edited a comment on issue #10181:
This particular example https://github.com/bytecodealliance/wasmtime/issues/10181#issuecomment-2665004815 has fixed in local-built wasmtime (287e8fb5405a943f67babf08643e23bea449e7bf) :tada: not sure what was the fix though.
but we still hit the
Illegal instruction: 4error in larger binary, I'll share it when I could make a bit smaller reproducible example.
tanishiking edited a comment on issue #10181:
This particular example https://github.com/bytecodealliance/wasmtime/issues/10181#issuecomment-2665004815 has fixed in local-built wasmtime (287e8fb5405a943f67babf08643e23bea449e7bf) :tada: not sure what was the fix though.
We still hit the
Illegal instruction: 4error in larger binary, I'll share it when I could make a bit smaller reproducible example.
fitzgen commented on issue #10181:
@tanishiking could you check whether https://github.com/bytecodealliance/wasmtime/pull/10371 fixes the issue locally for you? It fixes illegal instruction faults for me locally (which are the externally visible symptoms of internal debug assertions inside the compiled Wasm code failing). Thanks!
Last updated: Dec 13 2025 at 19:03 UTC