-
-
Notifications
You must be signed in to change notification settings - Fork 32.9k
Closed
Labels
wasiIssues and PRs related to the WebAssembly System Interface.Issues and PRs related to the WebAssembly System Interface.workerIssues and PRs related to Worker support.Issues and PRs related to Worker support.
Description
Version: v14.2.0
Platform: Linux x1 5.6.11-arch1-1 #1 SMP PREEMPT Wed, 06 May 2020 17:32:37 +0000 x86_64 GNU/Linux
Subsystem: WASI, worker_threads
What steps will reproduce the bug?
The idea is that I want to detect long running code in a worker. And terminate the worker after some timeout (3000ms in my case). Everything is working fine for normal JS code in the worker. When I use WASM in my worker nodejs crashes with a fatal error (see stack trace further below)
Here is the minimal test case I could produce:
- Create a WASM file by compiling a C++ program with emscripten. The C++ program needs to have a long running task. I used an endless loop:
int main(int argc, char** argv) {
for(int i=0; i<100; ) {}
return 0;
}
- Load and run the WASM file inside the worker thread. Terminate the worker after some timeout. In the code below the runWASM function is run in the worker thread (by converting it to a string via toString() and setting eval to true in the worker options. The main function is run in the main thread:
async function runWASM(wasmFile) {
const fs = require('fs').promises
const { WASI } = require('wasi')
const wasi = new WASI({
args: [],
env: process.env,
preopens: {},
returnOnExit: true
})
const importObject = { wasi_snapshot_preview1: wasi.wasiImport }
let buf = await fs.readFile(wasmFile)
const wasm = await WebAssembly.compile(buf)
const instance = await WebAssembly.instantiate(wasm, importObject)
wasi.start(instance)
}
function main() {
const wt = require("worker_threads")
let wasmFile = "./program.wasm"
let worker = new wt.Worker(`${runWASM.toString()}\nrunWASM("${wasmFile}")`, {eval:true})
let timeoutId = setTimeout(() => {
console.log("terminating wasm worker")
worker.terminate()
}, 3000)
console.log("threadId", worker.threadId)
worker.on("exit", exitCode => {
clearTimeout(timeoutId)
console.log("exited", worker.threadId)
})
}
main()
How often does it reproduce? Is there a required condition?
Always reproducible
What is the expected behavior?
The worker thread is terminated and the main thread continues
What do you see instead?
NodeJS is crashing with
FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal.
1: 0x55ee3b6e9131 node::Abort() [node]
2: 0x55ee3b6262ce node::FatalError(char const*, char const*) [node]
3: 0x55ee3b86aa7b v8::Utils::ReportApiFailure(char const*, char const*) [node]
4: 0x55ee3b64ddf2 node::EmitBeforeExit(node::Environment*) [node]
5: 0x55ee3b7ae4ba node::worker::Worker::Run() [node]
6: 0x55ee3b7ae9c8 [node]
7: 0x7f4f80af846f [/usr/lib/libpthread.so.0]
8: 0x7f4f80a263d3 clone [/usr/lib/libc.so.6]
Additional information
Obviously I am using the experimental WASI interface. I therefore run node with
node --experimental-wasi-unstable-preview1 --experimental-wasm-bigint index.js
addaleax and gengjiawen
Metadata
Metadata
Assignees
Labels
wasiIssues and PRs related to the WebAssembly System Interface.Issues and PRs related to the WebAssembly System Interface.workerIssues and PRs related to Worker support.Issues and PRs related to Worker support.