From d230c6768edae482de7ca7856ecf35876de26bfd Mon Sep 17 00:00:00 2001 From: Bryan English Date: Sat, 19 Jun 2021 13:47:43 -0400 Subject: [PATCH] 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: https://github.com/nodejs/node/issues/39019 --- src/env-inl.h | 6 +++++- test/parallel/test-async-hooks-vm-gc.js | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-async-hooks-vm-gc.js diff --git a/src/env-inl.h b/src/env-inl.h index 6fb8f137c37569..1dacaa847c99e0 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -256,8 +256,12 @@ inline void AsyncHooks::RemoveContext(v8::Local ctx) { v8::Isolate* isolate = env()->isolate(); v8::HandleScope handle_scope(isolate); for (auto it = contexts_.begin(); it != contexts_.end(); it++) { + if (it->IsEmpty()) { + contexts_.erase(it); + break; + } v8::Local saved_context = - PersistentToLocal::Weak(env()->isolate(), *it); + PersistentToLocal::Weak(isolate, *it); if (saved_context == ctx) { it->Reset(); contexts_.erase(it); diff --git a/test/parallel/test-async-hooks-vm-gc.js b/test/parallel/test-async-hooks-vm-gc.js new file mode 100644 index 00000000000000..4a45c3ac2a0cbb --- /dev/null +++ b/test/parallel/test-async-hooks-vm-gc.js @@ -0,0 +1,15 @@ +// Flags: --expose-gc +'use strict'; + +require('../common'); +const asyncHooks = require('async_hooks'); +const vm = require('vm'); + +// This is a regression test for https://github.com/nodejs/node/issues/39019 +// +// It should not segfault. + +const hook = asyncHooks.createHook({ init() {} }).enable(); +vm.createContext(); +gc(); +hook.disable();