src: add cleanup hooks to node::ObjectWrap#63642
Conversation
Add cleanup hooks to make sure that addons making use of this legacy API can do so safely in Worker threads or embedder-controlled Node.js instances. Refs: nodejs#63575 Fixes: nodejs#63540 Signed-off-by: Anna Henningsen <anna@addaleax.net>
This content is taken from nodejs#63575. The original commit message is preserved below: --- worker: fix premature addon unload Weak callbacks could run after addons were unloaded, leading to a crash. Signed-off-by: Mohamed Akram <mohd.akram@outlook.com>
|
Review requested:
|
| if (!isMainThread) { | ||
| const addon = require(`./build/${common.buildType}/binding`); | ||
|
|
||
| // Create some garbage |
There was a problem hiding this comment.
Is this necessary to test with the CleanupHook? I don't think it is necessary to trigger GC here, right?
There was a problem hiding this comment.
You're right, GC would prevent the test case from working, if anything – done in fcb0a4d
There was a problem hiding this comment.
@legendecas @addaleax It's not meant to trigger a GC immediately. The purpose of the loop is to make sure the WeakCallback runs, which it does after the addon is unloaded, and therefore causes a segfault absent a fix. Without that loop you won't be testing the visible effects of the clean up hook (i.e. that it removes the WeakCallback). The loop iterations were chosen such that this happens consistently.
There was a problem hiding this comment.
@mohd-akram If the weak callback runs here, won't that mean that the object is destroyed before the Environment and therefore the issue in #63540 will actually not occur? I can reproduce a fairly consistent crash with current Node.js versions (i.e. before this PR) when the loop is commented out and no consistent crash when it is active.
There was a problem hiding this comment.
If the weak callback runs here, won't that mean that the object is destroyed before the Environment and therefore the issue in #63540 will actually not occur?
On my system, it doesn't run there, it runs after.
I can reproduce a fairly consistent crash with current Node.js versions (i.e. before this PR) when the loop is commented out and no consistent crash when it is active.
Hmm, that's surprising. Definitely the opposite happening for me:
$ cat test.js
'use strict';
const common = require('../../common');
const { isMainThread, Worker } = require('worker_threads');
if (!isMainThread) {
const addon = require(`./build/${common.buildType}/binding`);
// Create some garbage
const arr = [];
for (let i = 0; i < 1e5; i++) arr.push(`${i}`.repeat(100));
new addon.MyObject(10);
// Should not segfault
throw new Error('exit');
} else {
const worker = new Worker(__filename);
worker.on('error', () => {});
}
$ node --version
v26.2.0
$ node test.js
zsh: segmentation fault node test.js
What OS are you on?
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #63642 +/- ##
==========================================
+ Coverage 90.30% 90.33% +0.03%
==========================================
Files 730 732 +2
Lines 234802 236357 +1555
Branches 43957 44491 +534
==========================================
+ Hits 212041 213523 +1482
- Misses 14485 14548 +63
- Partials 8276 8286 +10 🚀 New features to boost your workflow:
|
In two commits to keep attribution to @mohd-akram's PR intact. If somebody feels strongly that they should be a single commit, I can turn them into one with a
Co-authored-bytag.src: add cleanup hooks to
node::ObjectWrapAdd cleanup hooks to make sure that addons making use
of this legacy API can do so safely in Worker threads
or embedder-controlled Node.js instances.
Refs: #63575
Fixes: #63540
test: add regression test for using
ObjectWrapin workerThis content is taken from #63575.
The original commit message is preserved below: