Skip to content

Commit 48e5971

Browse files
benglMylesBorins
authored andcommitted
async_hooks: check for empty contexts before removing
This way we don't end up attempting to SetPromiseHooks on contexts that have already been collected. Fixes: #39019 PR-URL: #39095 Backport-PR-URL: #38577 Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Gerhard Stöbich <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Andrey Pechkurov <[email protected]> Reviewed-By: Danielle Adams <[email protected]>
1 parent 691c00c commit 48e5971

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

src/env-inl.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ inline void AsyncHooks::SetJSPromiseHooks(v8::Local<v8::Function> init,
127127
js_promise_hooks_[2].Reset(env()->isolate(), after);
128128
js_promise_hooks_[3].Reset(env()->isolate(), resolve);
129129
for (auto it = contexts_.begin(); it != contexts_.end(); it++) {
130+
if (it->IsEmpty()) {
131+
it = contexts_.erase(it);
132+
it--;
133+
continue;
134+
}
130135
PersistentToLocal::Weak(env()->isolate(), *it)
131136
->SetPromiseHooks(init, before, after, resolve);
132137
}
@@ -279,8 +284,13 @@ inline void AsyncHooks::RemoveContext(v8::Local<v8::Context> ctx) {
279284
v8::Isolate* isolate = env()->isolate();
280285
v8::HandleScope handle_scope(isolate);
281286
for (auto it = contexts_.begin(); it != contexts_.end(); it++) {
287+
if (it->IsEmpty()) {
288+
it = contexts_.erase(it);
289+
it--;
290+
continue;
291+
}
282292
v8::Local<v8::Context> saved_context =
283-
PersistentToLocal::Weak(env()->isolate(), *it);
293+
PersistentToLocal::Weak(isolate, *it);
284294
if (saved_context == ctx) {
285295
it->Reset();
286296
contexts_.erase(it);
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Flags: --expose-gc
2+
'use strict';
3+
4+
require('../common');
5+
const asyncHooks = require('async_hooks');
6+
const vm = require('vm');
7+
8+
// This is a regression test for https://github.com/nodejs/node/issues/39019
9+
//
10+
// It should not segfault.
11+
12+
const hook = asyncHooks.createHook({ init() {} }).enable();
13+
vm.createContext();
14+
globalThis.gc();
15+
hook.disable();

0 commit comments

Comments
 (0)