WebAssembly / design

WebAssembly Design Documents
http://webassembly.org
Apache License 2.0
11.4k stars 694 forks source link

Standardize execution timeouts #1380

Open SoniEx2 opened 3 years ago

SoniEx2 commented 3 years ago

Browsers already define trap on loop semantics. If a script "hangs" (takes too long to return back to the browser), the browser gives the user the option to kill the script. It'd be nice if trapping on loop, br, etc was formally a thing.

conrad-watt commented 3 years ago

Browsers aren't detecting infinite loops, they're counting down a time limit since the web page/DOM was last responsive. For example, you can run an infinite loop in a Web worker without triggering the "kill script" popup. Your suggestion isn't something that can be implemented in Wasm's core semantics.

SoniEx2 commented 3 years ago

same difference tbh.

let it trap, either because of external time constraints or otherwise.

conrad-watt commented 3 years ago

let it trap, either because of external time constraints or otherwise.

The "or otherwise" is important, because every Wasm host is going to want to do something different. I suppose we could weaken the language here (https://webassembly.github.io/spec/core/appendix/implementation.html#execution) to explicitly allow this kind of "exhaustion error", or similarly add a non-normative note to this effect - is this what you're hoping for?

SoniEx2 commented 3 years ago

yeah.

SoniEx2 commented 3 years ago

our particular use-case for this is https://github.com/MightyPirates/OpenComputers but as long as we can trap on time limits it's fine.

titzer commented 3 years ago

A wasm engine inside of Minecraft? I say why not!

SoniEx2 commented 3 years ago

or just a port of hexchat inside minecraft tbh :v

anyway, this is off-topic

lars-t-hansen commented 3 years ago

I'd be curious to know why a counter in a global plus this kind of code:

if (!--counter) { unreachable }

inserted by the compiler at function entry and loop heads would not be good enough? Or is the problem that you want to control what the browser gets to do if it times out, or that you want a notification if it did time out?

SoniEx2 commented 3 years ago

because we're not the compiler. we're the VM. and malicious wasm is a thing.

tlively commented 3 years ago

You could perform that code transformation as the first step to load code in your VM so that you don't have to trust the user to do it.

SoniEx2 commented 3 years ago

what if it's done by using a watchdog thread, or even a hardware watchdog, and interrupting the wasm thread/CPU?

Macil commented 3 years ago

Related: https://github.com/ewasm/wasm-metering is an example of a project which pre-processes a webassembly binary to add step metering and timeouts.

immibis commented 3 years ago

As far as I'm aware, OpenComputers doesn't even have timeouts. It implements pre-emptive multitasking - you can have all the infinite loops you want, and when your time-slice is up, your state gets saved and control is transferred elsewhere.

SoniEx2 commented 3 years ago

It has 4 threads (number may vary between computers) but it uses cooperative multitasking, and Lua debug hooks to stop misbehaving/uncooperating computers.

SoniEx2 commented 3 years ago

Oh also, wasmtime has call and loop hooks, for this reason.

immibis commented 3 years ago

because we're not the compiler. we're the VM. and malicious wasm is a thing.

Even better. Since you're the VM, you can do whatever the hell you like. You can implement your own pre-emptive multitasking!

Since OpenComputers suspends the program and later resumes it and doesn't have shared memory, I'm not sure why it matters where it gets suspended.

AFAIK in browsers the entire page is in some kind of crashed state after you abort a script. Ditto. You basically have undefined (safe) behaviour at that point.