Stream: git-wasmtime

Topic: wasmtime / issue #11387 Output difference between interpr...


view this post on Zulip Wasmtime GitHub notifications bot (Aug 06 2025 at 19:54):

teyahb8 opened issue #11387:

Test Case

Wasm file: wasm-58-test.txt
Wat file: wat-58-test.txt

Steps to Reproduce

  1. Rename wasm-58-test.txt to test.wasm
  2. For wasmtime interpreter, run: wasmtime -W all-proposals=y --invoke _start test.wasm
  3. For wasmtime compiled, run: wasmtime compile -W all-proposals=y test.wasm -o test.cwasm
    run: wasmtime -W all-proposals=y --allow-precompiled --invoke _start test.cwasm

Expected Results

Based on execution from other runtimes like the wasm-micro-runtime and also wasmtime's interpreter mode, the expected output might be stack overflow.

Actual Results

Compiled mode outputs:

Error: failed to run main module `58-path_exists.cwasm`

Caused by:
    0: failed to invoke `_start`
    1: error while executing at wasm backtrace:
           0:   0xc373 - <unknown>!<wasm function 240>
           1:   0x7bfc - <unknown>!<wasm function 168>
           2:  0x131c2 - <unknown>!<wasm function 305>
           3:   0xb1d4 - <unknown>!<wasm function 222>
           4:   0xbd9e - <unknown>!<wasm function 233>
           5:   0xb119 - <unknown>!<wasm function 221>
           6:   0xb07d - <unknown>!<wasm function 220>
           7:   0xba81 - <unknown>!<wasm function 228>
           8:  0x126b7 - <unknown>!<wasm function 297>
           9:  0x14cb5 - <unknown>!<wasm function 330>
          10:   0x876b - <unknown>!<wasm function 184>
          11:   0xa4ba - <unknown>!<wasm function 207>
          12:   0xa9d9 - <unknown>!<wasm function 209>
          13:   0x21a7 - <unknown>!<wasm function 61>
          14:    0xe88 - <unknown>!<wasm function 34>
          15:   0x1256 - <unknown>!<wasm function 48>
          16:    0xcf4 - <unknown>!<wasm function 29>
          17:    0xe48 - <unknown>!<wasm function 33>
          18:    0xe1d - <unknown>!<wasm function 32>
          19:   0x9430 - <unknown>!<wasm function 196>
          20:    0xc93 - <unknown>!<wasm function 28>
          21:   0x23d9 - <unknown>!<wasm function 62>
          22:    0x5d1 - <unknown>!<wasm function 17>
    2: Pointer out of bounds: Region { start: 4294967058, len: 4 }

Versions and Environment

Wasmtime version or commit: wasmtime 37.0.0 (3cbeb24bc 2025-08-06)

Operating system: Ubuntu 22.04

Architecture: x86_64

Extra Info

Can you please confirm which output should be the correct output and which mode might be incorrect? Thanks in advance?

view this post on Zulip Wasmtime GitHub notifications bot (Aug 06 2025 at 19:54):

teyahb8 added the bug label to Issue #11387.

view this post on Zulip Wasmtime GitHub notifications bot (Aug 06 2025 at 20:58):

pchickey closed issue #11387:

Test Case

Wasm file: wasm-58-test.txt
Wat file: wat-58-test.txt

Steps to Reproduce

  1. Rename wasm-58-test.txt to test.wasm
  2. For wasmtime interpreter, run: wasmtime -W all-proposals=y --invoke _start test.wasm
  3. For wasmtime compiled, run: wasmtime compile -W all-proposals=y test.wasm -o test.cwasm
    run: wasmtime -W all-proposals=y --allow-precompiled --invoke _start test.cwasm

Expected Results

Based on execution from other runtimes like the wasm-micro-runtime and also wasmtime's interpreter mode, the expected output might be stack overflow.

Actual Results

Compiled mode outputs:

Error: failed to run main module `58-path_exists.cwasm`

Caused by:
    0: failed to invoke `_start`
    1: error while executing at wasm backtrace:
           0:   0xc373 - <unknown>!<wasm function 240>
           1:   0x7bfc - <unknown>!<wasm function 168>
           2:  0x131c2 - <unknown>!<wasm function 305>
           3:   0xb1d4 - <unknown>!<wasm function 222>
           4:   0xbd9e - <unknown>!<wasm function 233>
           5:   0xb119 - <unknown>!<wasm function 221>
           6:   0xb07d - <unknown>!<wasm function 220>
           7:   0xba81 - <unknown>!<wasm function 228>
           8:  0x126b7 - <unknown>!<wasm function 297>
           9:  0x14cb5 - <unknown>!<wasm function 330>
          10:   0x876b - <unknown>!<wasm function 184>
          11:   0xa4ba - <unknown>!<wasm function 207>
          12:   0xa9d9 - <unknown>!<wasm function 209>
          13:   0x21a7 - <unknown>!<wasm function 61>
          14:    0xe88 - <unknown>!<wasm function 34>
          15:   0x1256 - <unknown>!<wasm function 48>
          16:    0xcf4 - <unknown>!<wasm function 29>
          17:    0xe48 - <unknown>!<wasm function 33>
          18:    0xe1d - <unknown>!<wasm function 32>
          19:   0x9430 - <unknown>!<wasm function 196>
          20:    0xc93 - <unknown>!<wasm function 28>
          21:   0x23d9 - <unknown>!<wasm function 62>
          22:    0x5d1 - <unknown>!<wasm function 17>
    2: Pointer out of bounds: Region { start: 4294967058, len: 4 }

Versions and Environment

Wasmtime version or commit: wasmtime 37.0.0 (3cbeb24bc 2025-08-06)

Operating system: Ubuntu 22.04

Architecture: x86_64

Extra Info

Can you please confirm which output should be the correct output and which mode might be incorrect? Thanks in advance?

view this post on Zulip Wasmtime GitHub notifications bot (Aug 06 2025 at 20:58):

pchickey commented on issue #11387:

It looks like instead of getting an overflow on the wasm control stack, as you do in wasmtimes winch backend or in wamr, you are instead getting an underflow on LLVM's shadow stack. This is down to implementation details of the wasm control stack size between implementations. The spec describes that the number of frames on the stack may be restricted, and the exact restriction is allowed to vary by implementation.

view this post on Zulip Wasmtime GitHub notifications bot (Aug 06 2025 at 21:00):

pchickey edited a comment on issue #11387:

It looks like instead of getting an overflow on the wasm control stack, as you do in wasmtimes winch backend or in wamr, you are instead getting an underflow on LLVM's shadow stack. This is down to implementation details of the wasm control stack size between implementations. The spec describes that the number of frames on the stack may be restricted, and the exact restriction is allowed to vary by implementation.

Please inspect your bug reports for these sort of allowable spec differences in the future.

view this post on Zulip Wasmtime GitHub notifications bot (Aug 06 2025 at 21:14):

teyahb8 commented on issue #11387:

Thanks for the explanation, @pchickey. So, is there a way to definitely say which is the correct output between stack overflow and pointer out of bounds?

view this post on Zulip Wasmtime GitHub notifications bot (Aug 06 2025 at 21:59):

pchickey commented on issue #11387:

Either output is correct for this program.

view this post on Zulip Wasmtime GitHub notifications bot (Aug 06 2025 at 22:05):

teyahb8 commented on issue #11387:

That makes sense. Thanks for the clarification. But, I still think that it might be better for any single runtime to be consistent across multiple modes within itself. In this case, getting the same output for both the interpreter and the compiled modes of Wasmtime might be desirable.

view this post on Zulip Wasmtime GitHub notifications bot (Aug 06 2025 at 23:49):

pchickey commented on issue #11387:

It could be desirable in the absence of any other tradeoffs, but the tradeoff there is, to a first approximation, that cranelift is allowed to generate the best native stack frames it can manage instead of having to pad them out to whatever stack frame size the winch implementation happens to be. This would needlessly degrade performance for anyone using cranelift on programs that dont reach the stack limit, which in practice is 100% of the programs we care about executing. In practice this behavior has never bothered anyone writing real programs because they don't reach the default max stack size that wasmtime settled on. And, if hypothetically tomorrow llvm was to start spitting out wasm that blew past wasmtime's default limit, wasmtime embedders would make a single-line commit to increase https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.max_wasm_stack and care about other problems instead.

Put another way, I dont really think this particular behavior matters to anyone besides someone fuzzing around to find differences between runtimes in badly-behaved wasm programs.

view this post on Zulip Wasmtime GitHub notifications bot (Aug 06 2025 at 23:49):

pchickey edited a comment on issue #11387:

It could be desirable in the absence of any other tradeoffs, but the tradeoff there is, to a first approximation, that cranelift is allowed to generate the best native stack frames it can manage instead of having to pad them out to whatever stack frame size the winch implementation happens to be. This would needlessly degrade performance for anyone using cranelift on programs that dont reach the stack limit, which in practice is 100% of the programs we care about executing. In practice this behavior has never bothered anyone writing real programs because they don't reach the default max stack size that wasmtime settled on. And, if hypothetically tomorrow llvm was to start spitting out wasm that blew past wasmtime's default limit, wasmtime embedders would make a single-line commit to increase https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.max_wasm_stack and move on to caring about other problems instead.

Put another way, I dont really think this particular behavior matters to anyone besides someone fuzzing around to find differences between runtimes in badly-behaved wasm programs.

view this post on Zulip Wasmtime GitHub notifications bot (Aug 07 2025 at 00:06):

pchickey edited a comment on issue #11387:

It could be desirable in the absence of any other tradeoffs, but the tradeoff there is, to a first approximation, that cranelift is allowed to generate the best native stack frames it can manage instead of having to pad them out to whatever stack frame size the winch implementation happens to be. This would needlessly degrade performance for anyone using cranelift on programs that dont reach the stack limit, which in practice is 100% of the programs we care about executing. In practice this behavior has never bothered anyone writing real programs because they don't reach the default max stack size that wasmtime settled on. And, if hypothetically tomorrow llvm was to start spitting out wasm for non-pathological programs that blew past wasmtime's default limit, wasmtime embedders would make a single-line commit to increase https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.max_wasm_stack and move on to caring about other problems instead.

Put another way, I dont really think this particular behavior matters to anyone besides someone fuzzing around to find differences between runtimes in badly-behaved wasm programs.

view this post on Zulip Wasmtime GitHub notifications bot (Aug 07 2025 at 01:29):

teyahb8 commented on issue #11387:

That is reasonable. Thanks for the feedback.


Last updated: Dec 06 2025 at 06:05 UTC