ITADN

ffi: refCallback()/unrefCallback() crash (SIGSEGV) when called on a garbage-collected callback

#64880Closedtrivikr 创建于 21 天前
ffi
T
trivikrcommented
### Version main ### Platform ```text N/A ``` ### Subsystem ffi ### What steps will reproduce the bug? `repro.c` ```c #include <stdint.h> int32_t noop(int32_t x) { return x; } ``` Compile it by running ```sh $ cc -shared -o repro.so repro.c # or .dylib on macOS ``` `repro.js` ```js import { DynamicLibrary, suffix } from 'node:ffi'; const lib = new DynamicLibrary(`./repro.${suffix}`); let cb = (x) => x + 1; const ptr = lib.registerCallback({ arguments: ['i32'], return: 'i32' }, cb); // Allow GC to collect the callback backing function lib.unrefCallback(ptr); cb = null; globalThis.gc(); // Second unref (or refCallback) on the now-empty weak handle → SIGSEGV lib.unrefCallback(ptr); lib.close(); ``` Run it using ```sh $ node --experimental-ffi --expose-gc --no-warnings repro.js ``` ### How often does it reproduce? Is there a required condition? Always ### What is the expected behavior? Why is that the expected behavior? `unrefCallback`/`refCallback` on a collected callback should throw `ERR_INVALID_ARG_VALUE("Callback not found")`. ### What do you see instead? ```console segmentation fault (core dumped) ``` The process crashes with `SIGSEGV` inside `v8::PersistentBase::SetWeak()` (or `ClearWeak()` for refCallback) because the weak handle slot is already cleared after GC. ### Additional information _No response_
关闭于 19 天前 1 条评论