Version
main
Platform
Subsystem
ffi
What steps will reproduce the bug?
import { Worker } from 'node:worker_threads';
// qsort() from the process image calls the JS comparator through node:ffi.
const workerSource = `
const { parentPort, workerData } = require('node:worker_threads');
const ffi = require('node:ffi');
const { lib, functions } = ffi.dlopen(null, {
qsort: { arguments: ['pointer', 'u64', 'u64', 'pointer'], return: 'void' },
});
const compare = lib.registerCallback(
{ arguments: ['pointer', 'pointer'], return: 'i32' },
() => {
if (workerData === 'exit') process.exit(0);
parentPort.postMessage('in callback');
for (;;);
},
);
const items = new Int32Array([2, 1]);
functions.qsort(ffi.getRawPointer(items), 2n, 4n, compare);
`;
const mode = process.argv[2];
const worker = new Worker(workerSource, { eval: true, workerData: mode });
worker.on('message', () => {
if (mode === 'shutdown') process.exit(0);
worker.terminate();
});
worker.on('exit', (code) => console.log(`worker exited with code ${code}`));
$ node --experimental-ffi repro.mjs shutdown # main thread calls process.exit(0) while the Worker is in the callback
$ node --experimental-ffi repro.mjs terminate # worker.terminate() while the Worker is in the callback
$ node --experimental-ffi repro.mjs exit # process.exit() inside the callback
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
Only the Worker stops:
# shutdown: exit code 0
worker exited with code 1 # terminate
worker exited with code 0 # exit
The docs say that process.exit() in a Worker "stops the current thread rather than the current process", and that worker.terminate() stops "JavaScript execution in the worker thread". Neither of these is an exception thrown by the callback.
What do you see instead?
All three modes abort the whole process with exit code 134:
Callbacks cannot throw an exception
----- Native stack trace -----
1: 0x102c5f1b8 node::(anonymous namespace)::DefaultAbortHandler(char const*, char const*)
2: 0x102cd8cfc node::ffi::DynamicLibrary::InvokeCallback(ffi_cif*, void*, void**, void*) (.cold.5)
3: 0x1008e5bc8 node::ffi::DynamicLibrary::InvokeCallback(ffi_cif*, void*, void**, void*)
4: 0x101f5e338 ffi_closure_SYSV_inner
...
Additional information
No response
Version
main
Platform
Subsystem
ffi
What steps will reproduce the bug?
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
Only the Worker stops:
The docs say that
process.exit()in a Worker "stops the current thread rather than the current process", and thatworker.terminate()stops "JavaScript execution in the worker thread". Neither of these is an exception thrown by the callback.What do you see instead?
All three modes abort the whole process with exit code 134:
Additional information
No response