Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closing a worker in certain steps of the event loop tick can result in a panic #12263

Closed
andreubotella opened this issue Sep 29, 2021 · 3 comments
Labels
bug Something isn't working correctly web related to Web APIs

Comments

@andreubotella
Copy link
Contributor

andreubotella commented Sep 29, 2021

// main.js
new Worker(new URL("./worker.js", import.meta.url), {type: "module"});
// worker.js

// The minimum valid wasm module, plus two additional zero bytes.
const buffer = new Uint8Array([0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00]);
WebAssembly.compile(buffer).catch(err => {
  console.log("Error:", err);
  self.close();
});
Error: CompileError: WebAssembly.compile(): expected string length @+10
thread 'worker-0' panicked at 'called `Option::unwrap()` on a `None` value', core/runtime.rs:1577:29
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The promise returned by a call to WebAssembly.compile() can resolve either synchronously, in which case its reactions will be immediately enqueued in the microtask queue; or asynchronously, in which case the V8 message loop has to be pumped before the reactions are enqueued. It seems like cases where the byte source doesn't match the WASM prefix, or where the byte source is the WASM prefix, are handled synchronously – while cases that need non-trivial parsing of the WASM module are async.

Now, Deno pumps the message loop, followed by performing a microtask checkpoint, at the beginning of each tick of the event loop. In the above case, this will result in self.close() being called, which terminates the execution of the worker's isolate, while there are still pending operations in the tick of the event loop. In particular, JsRuntime::drain_macrotasks() calls into a JS function and does not expect it to return None without there being an exception, resulting in a panic.

I'm not sure if there's anything else in the event loop that runs JS code and might break if the isolate has been terminated. Module loading maybe?

@andreubotella andreubotella changed the title Closing a worker in the reactions of a WASM async operation can panic Closing a worker in the reactions of a WASM async operation can result in a panic Sep 29, 2021
andreubotella pushed a commit to andreubotella/deno that referenced this issue Sep 29, 2021
@andreubotella andreubotella changed the title Closing a worker in the reactions of a WASM async operation can result in a panic Closing a worker in certain steps of the event loop tick can result in a panic Sep 30, 2021
@andreubotella
Copy link
Contributor Author

andreubotella commented Sep 30, 2021

Changed the title to make this issue more general, since there might be other ways to trigger this panic other than WASM compilation.

@andreubotella
Copy link
Contributor Author

For the record, the test case in the OP doesn't panic anymore after #12270.

@bartlomieju bartlomieju added bug Something isn't working correctly web related to Web APIs labels Oct 13, 2021
@bartlomieju
Copy link
Member

I'm going to close this issue with #12270 and #12831 landed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working correctly web related to Web APIs
Projects
None yet
Development

No branches or pull requests

2 participants