iwasm doesn't respect timeout in start function execution
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?
🤔 Something like #2163 and https://github.com/bytecodealliance/wasm-micro-runtime/issues/3927
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
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.
"roughly the number of loop iterations and function calls" Oh, yes, i meant exactly that!
Let's say you run
iwasm --timeout=4000 foo.wasmIf
foo.wasmhas 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 callingwasm_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
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
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.
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.