teyahb8 added the bug label to Issue #10169.
teyahb8 opened issue #10169:
Test Case
The wat code and the corresponding wasm module are compressed here: files.zip
Steps to Reproduce
- Extract the files from the compressed file
- Run
wat2wasm 366.wat
- Run
wasmtime --invoke main 366.wasm
Expected Results
Based on the differential behavior of
wasmer
,wamr (aot mode)
, andwasmedge
runtimes, the expected behavior is anout of bounds
error.Actual Results
The actual result from the
wasmtime
runtime is astack overflow
.Versions and Environment
Wasmtime version or commit: wasmtime 28.0.0 (3e0b7e501 2024-11-19)
Operating system: Linux
Architecture: x86_64
Can you please confirm if this behavior is expected from
wasmtime
or is this a bug? Thanks in advance.
teyahb8 edited issue #10169:
Test Case
The wat code and the corresponding wasm module are compressed here: files.zip
Steps to Reproduce
- Extract the files from the compressed file
- Run
wat2wasm 366.wat
- Run
wasmtime --invoke main 366.wasm
Expected Results
Based on the differential behavior of
wasmer
,wamr (aot mode)
, andwasmedge
runtimes, the expected behavior is anout of bounds
error.Actual Results
The actual result from the
wasmtime
runtime is astack overflow
.Versions and Environment
Wasmtime version or commit: wasmtime 30.0.0 (a0338af84 2025-01-31)
Operating system: Linux
Architecture: x86_64
Can you please confirm if this behavior is expected from
wasmtime
or is this a bug? Thanks in advance.
cfallin commented on issue #10169:
@teyahb8 in the future, would you mind posting the example directly? Posting a link to a .zip file that must be downloaded and extracted to view, especially when that
.zip
file is 506 bytes and the resulting WAT is 13 lines, is fairly wasteful of maintainers' time. Thanks!The test-case is:
(module (memory (;0;) 25) (export "main" (func 0)) (func (;0;) (result) i32.const 2 memory.grow v128.load offset=2 align=2 block (result) ;; label = @1 call 0 end drop ) )
This program recurses, and on each recursion grows the memory by 2 Wasm pages (128 KiB). The memory does not have a limit (the
25
is its initial size in Wasm pages), so it will grow up to 4GiB, or about 32K recursions (4Gi / 128 Ki, minus initial 25 pages).It seems unsurprising to me that a program that recurses 32K times runs out of stack. Perhaps the other Wasm engines have different default stack sizes, or allocate a different (smaller) frame per function. Stack exhaustion is one of several sources of engine-specific nondeterminism in Wasm, so if you're running tests of engines against each other, you will need to account for that.
Given all that, I think this is not a bug, just nondeterminism allowed by the spec. Do you agree? Or is there something I'm missing?
cfallin commented on issue #10169:
(And lest the
v128.load
raise suspicions, it is performing a load from an address based on the returned new memory size in pages, but treating that as a byte-addressed location; so it is always in-bounds.)
primoly commented on issue #10169:
If the
memory.grow
fails due to the host not having enough memory, it returns -1 (=2<sup>32</sup>-1) leading to an out of bounds memory access.I tested it in Firefox and it seems to run out of stack as well. I can’t test the other runtimes right now, but could it be that they do some sort of tail-call optimisation? I think that would go against the WebAssembly spec.
alexcrichton closed issue #10169:
Test Case
The wat code and the corresponding wasm module are compressed here: files.zip
Steps to Reproduce
- Extract the files from the compressed file
- Run
wat2wasm 366.wat
- Run
wasmtime --invoke main 366.wasm
Expected Results
Based on the differential behavior of
wasmer
,wamr (aot mode)
, andwasmedge
runtimes, the expected behavior is anout of bounds
error.Actual Results
The actual result from the
wasmtime
runtime is astack overflow
.Versions and Environment
Wasmtime version or commit: wasmtime 30.0.0 (a0338af84 2025-01-31)
Operating system: Linux
Architecture: x86_64
Can you please confirm if this behavior is expected from
wasmtime
or is this a bug? Thanks in advance.
alexcrichton commented on issue #10169:
I agree with @cfallin and @primoly in that there doesn't look to be a bug here. At best other runtimes have different defaults for when stack overflow occurs and at worst other runtimes are going against the spec as @primoly mentions. In either case resource exhaustion is not specified to be the exact same across all runtimes so I don't think there's anything for Wasmtime to do here, so closing.
I would also echo what @cfallin said, avoiding the indirection of a zip is much appreciated.
primoly edited a comment on issue #10169:
If the
memory.grow
fails due to the host not having enough memory, it returns -1 (=2<sup>32</sup>-1) leading to an out of bounds memory access.I tested it in Edge and it seems to run out of stack as well. I can’t test the other runtimes right now, but could it be that they do some sort of tail-call optimisation? I think that would go against the WebAssembly spec.
teyahb8 commented on issue #10169:
Thanks for the clarification. I agree that the default stack exhaustion behavior can vary. Also, I appreciate the advice on the test case file format. I will make sure to keep this in mind for future issues.
Last updated: Feb 28 2025 at 02:27 UTC