ffi: do not abort when a Worker stops in a callback · nodejs/node@c65a333 · GitHub
Skip to content

Commit c65a333

Browse files
trivikraduh95
authored andcommitted
ffi: do not abort when a Worker stops in a callback
Stopping a Worker while it is running an FFI callback aborted the whole process with "Callbacks cannot throw an exception". This happened on worker.terminate(), on process.exit() inside the callback, and when the main thread exited while the Worker was in a callback, since exit terminates all Workers. All three stop the Worker by terminating execution, and InvokeCallback treated the termination as a thrown exception. Check HasTerminated() first and return a zeroed result so the native caller can unwind. Callbacks that throw still abort. Signed-off-by: Trivikram Kamat <16024985+trivikr@users.noreply.github.com> Assisted-by: claude:opus-5.5 PR-URL: #66389 Fixes: #66388 Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent fe76deb commit c65a333

4 files changed

Lines changed: 73 additions & 0 deletions

File tree

‎doc/api/ffi.md‎

Lines changed: 8 additions & 0 deletions

‎src/node_ffi.cc‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,16 @@ void DynamicLibrary::InvokeCallback(ffi_cif* cif,
768768
MaybeLocal<Value> result = callback->Call(
769769
context, Undefined(isolate), expected_args, callback_args.data());
770770

771+
// Termination (worker.terminate(), process.exit() in a Worker, or
772+
// environment teardown) is not an exception thrown by the callback.
773+
// Return a zeroed result and let the caller unwind.
774+
if (try_catch.HasTerminated()) {
775+
if (ret != nullptr && cb->return_type->size > 0) {
776+
std::memset(ret, 0, GetFFIReturnValueStorageSize(cb->return_type));
777+
}
778+
return;
779+
}
780+
771781
// Handle exceptions by crashing (can't propagate across FFI boundary)
772782
if (try_catch.HasCaught()) {
773783
FPrintF(stderr, "Callbacks cannot throw an exception\n");

‎test/ffi/ffi-callback-test-common.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ functions.call_int_callback(callback, 21);`,
4242
module.exports = {
4343
assertAborts,
4444
assertCallbackAborts,
45+
spawnAbortingChild,
4546
};
Lines changed: 54 additions & 0 deletions

0 commit comments

Comments
 (0)