Open
Description
Test case
Any WebAssembly module with control flow instructions (loops, branches) will reproduce this issue. A minimal test case would be:
(module
(func $test (export "test")
(loop $loop
br_if $loop (i32.const 1)
)
)
)
The issue occurs when setting an instruction limit and attempting to resume execution after hitting the limit.
Your environment
- Host OS: Debian 12 Bookworm
- WAMR version: 2.3.1
- Platform: Desktop
- CPU architecture: AMD64
- Running mode: Interpreter mode with fast interpreter or classic interpreter
- Build configuration:
WASM_ENABLE_INSTRUCTION_METERING=1
Steps to reproduce
- Enable instruction metering:
WASM_ENABLE_INSTRUCTION_METERING=1
- Create a WASM module with control flow instructions (loops, branches like the test case above)
- Set an instruction limit (e.g., 100-1000 instructions) using
wasm_runtime_set_instruction_count_limit(...)
- Execute a function until it hits the instruction limit
- Resume execution by calling function
- Continue execution
Expected behavior
When instruction metering hits the configured limit:
- Execution should pause cleanly with the "instruction limit exceeded" exception
- The execution state (instruction pointer, stack, locals) should be preserved
- When resuming with a new instruction count, execution should continue from exactly where it left off
- The same instructions should not be re-executed from the beginning
Actual behavior
- First execution works correctly until instruction limit is reached
- When resuming, execution appears to restart from the beginning
- The same instructions are executed again (no resume from last instruction)
- Eventually crashes with "unreachable" exception (
Exception: unreachable
) when encountering aWASM_OP_BR_IF
- This suggests the execution state/stack is corrupted during the pause/resume cycle
Extra Info
The issue appears to be in the instruction metering implementation in wasm_interp_fast.c
and wasm_interp_classic.c
. There is no frame restoration logic may not properly preserve all necessary execution state when instruction metering interrupts execution.
I would be happy to work on solving this issue However, I would need some guidance from the maintainers on:
- Which execution state components need to be preserved?
- Memory allocation considerations:
- Do we need to handle any allocations that might be partially completed when instruction limit is hit?
- Are there any cleanup operations needed before suspension?
- Synchronization points:
- What constitutes a "safe" point for instruction metering interruption?
- Should we only check instruction limits at specific instruction boundaries?
Any guidance on these aspects would help me to fix this issue.
Metadata
Metadata
Assignees
Labels
No labels