Commit 670a0772fe8 for nodejs
commit 670a0772fe8b25002789b5d27cd5a1b44cb9c468
Author: Shelley Vohr <shelley.vohr@gmail.com>
Date: Tue Sep 22 13:48:46 2026 +0000
src: assert that an IsolateData outlives its Environments
FreeIsolateData() while an Environment created from it is still alive
left that Environment with a dangling pointer and failed later in
unrelated code. Count the Environments using an IsolateData and CHECK
in its destructor that none are left.
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66239
Refs: https://github.com/nodejs/node/pull/65977
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
diff --git a/src/env.cc b/src/env.cc
index f429c44ee75..e96b6e6bb12 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -651,7 +651,10 @@ IsolateData::IsolateData(Isolate* isolate,
}
}
-IsolateData::~IsolateData() {}
+IsolateData::~IsolateData() {
+ // FreeIsolateData() before FreeEnvironment() of an Environment using it.
+ CHECK_EQ(environment_count_, 0);
+}
// Deprecated API, embedders should use v8::Object::Wrap() directly instead.
void SetCppgcReference(Isolate* isolate,
@@ -983,6 +986,7 @@ Environment::Environment(IsolateData* isolate_data,
? AllocateEnvironmentThreadId().id
: thread_id.id),
thread_name_(thread_name) {
+ isolate_data->AddEnvironment();
#if HAVE_OPENSSL && NCRYPTO_USE_OPENSSL3_PROVIDER
provider_digest_cache = std::make_unique<ncrypto::DigestCache>();
provider_cipher_cache = std::make_unique<ncrypto::CipherCache>();
@@ -1304,6 +1308,7 @@ Environment::~Environment() {
cpu_profiler_->Dispose();
cpu_profiler_ = nullptr;
}
+ isolate_data_->RemoveEnvironment();
}
void Environment::InitializeLibuv() {
diff --git a/src/env.h b/src/env.h
index 8e132ed42ac..75f3a66eda7 100644
--- a/src/env.h
+++ b/src/env.h
@@ -182,6 +182,9 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
inline worker::Worker* worker_context() const;
inline void set_worker_context(worker::Worker* context);
+ void AddEnvironment() { environment_count_++; }
+ void RemoveEnvironment() { environment_count_--; }
+
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
@@ -283,6 +286,7 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
std::shared_ptr<PerIsolateOptions> options_;
worker::Worker* worker_context_ = nullptr;
+ size_t environment_count_ = 0;
PerIsolateWrapperData* wrapper_data_;
static Mutex isolate_data_mutex_;