wasm-micro-runtime icon indicating copy to clipboard operation
wasm-micro-runtime copied to clipboard

iwasm doesn't respect timeout in start function execution

Open sjamesr opened this issue 11 months ago • 8 comments

Let's say you run

iwasm --timeout=4000 foo.wasm

If foo.wasm has a start function with an infinite loop (e.g. due to a bug), the intepreter is not able to interrupt execution after 4 seconds. The interpreter will try to interrupt modules by calling wasm_runtime_terminate, but this requires a module instance, and obviously in this case module instantiation cannot finish.

What do you all think of adding some mechanism to interrupt the start function after a period of time? Is there a way to do this that I'm missing?

sjamesr avatar Jan 22 '25 21:01 sjamesr

🤔 Something like #2163 and https://github.com/bytecodealliance/wasm-micro-runtime/issues/3927

lum1n0us avatar Jan 22 '25 23:01 lum1n0us

I don't know how it's done in similar projects(like gas metering from wasmtime mentioned above), but i think adding parameter limiting control instructions(or limiting call nesting) would be probably a solution for things like infinite loops

hovertank3d avatar Feb 08 '25 16:02 hovertank3d

like --fuel of wasm-tools smith?

  -f, --fuel <FUEL>
          The default amount of fuel used with `--ensure-termination`.
          
          This is roughly the number of loop iterations and function calls that will be executed before a trap is raised to prevent infinite loops.

lum1n0us avatar Feb 09 '25 11:02 lum1n0us

"roughly the number of loop iterations and function calls" Oh, yes, i meant exactly that!

hovertank3d avatar Feb 09 '25 12:02 hovertank3d

Let's say you run

iwasm --timeout=4000 foo.wasm

If foo.wasm has a start function with an infinite loop (e.g. due to a bug), the intepreter is not able to interrupt execution after 4 seconds. The interpreter will try to interrupt modules by calling wasm_runtime_terminate, but this requires a module instance, and obviously in this case module instantiation cannot finish.

What do you all think of adding some mechanism to interrupt the start function after a period of time? Is there a way to do this that I'm missing?

you are right it's impossible with the current api to terminate instances in that state.

a possible solution is to separate the instantiation to two steps, similarly to: https://github.com/yamt/toywasm/blob/6cdb84116abb930e903221231dd657ec08fec9e2/lib/instance.h#L31-L45

yamt avatar Feb 10 '25 04:02 yamt

https://github.com/bytecodealliance/wasm-micro-runtime/pull/4072

Demo:

$ ./iwasm --timeout=4000 /tmp/out.wasm          # out.wasm has a start func with an infinite loop
WASM module instantiate failed: Exception: terminated by user    # happens 4s later

sjamesr avatar Feb 10 '25 06:02 sjamesr

I don't know what to do in the multi-module case, presumably all start functions have to be deferred until the user calls run_start_func on the root module. But before I started solving that, I just wanted to know what everybody thought of the approach in general.

sjamesr avatar Feb 10 '25 06:02 sjamesr

I don't know how it's done in similar projects(like gas metering from wasmtime mentioned above), but i think adding parameter limiting control instructions(or limiting call nesting) would be probably a solution for things like infinite loops

That would also enable asynchronous / cooperative scheduling (with a kind of pre-emptive control over WASM), which would be highly valuable for bindings that support async execution (e.g., Rust). However, it's unclear to me if that is the intended approach here.

AlixANNERAUD avatar Feb 19 '25 14:02 AlixANNERAUD