From 43e5478e2f51343b66f4d243bb4800d8e422f764 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Wed, 19 Jun 2019 19:24:14 -0700 Subject: domain: use strong reference to domain while active When an uncaught exception is thrown inside a domain, the domain is removed from the stack as of 43a51708589ac789ce08beaeb49d6d778dfbdc49. This means that it might not be kept alive as an object anymore, and may be garbage collected before the `after()` hook can run, which tries to exit it as well. Resolve that by making references to the domain strong while it is active. Fixes: https://github.com/nodejs/node/issues/28275 PR-URL: https://github.com/nodejs/node/pull/28313 Reviewed-By: Ben Noordhuis Reviewed-By: Vladimir de Turckheim Reviewed-By: Rich Trott --- src/node_util.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/node_util.cc') diff --git a/src/node_util.cc b/src/node_util.cc index 518865fe53..fa39583b04 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -189,12 +189,26 @@ class WeakReference : public BaseObject { args.GetReturnValue().Set(weak_ref->target_.Get(isolate)); } + static void IncRef(const FunctionCallbackInfo& args) { + WeakReference* weak_ref = Unwrap(args.Holder()); + if (weak_ref->reference_count_ == 0) weak_ref->target_.ClearWeak(); + weak_ref->reference_count_++; + } + + static void DecRef(const FunctionCallbackInfo& args) { + WeakReference* weak_ref = Unwrap(args.Holder()); + CHECK_GE(weak_ref->reference_count_, 1); + weak_ref->reference_count_--; + if (weak_ref->reference_count_ == 0) weak_ref->target_.SetWeak(); + } + SET_MEMORY_INFO_NAME(WeakReference) SET_SELF_SIZE(WeakReference) SET_NO_MEMORY_INFO() private: Global target_; + uint64_t reference_count_ = 0; }; static void GuessHandleType(const FunctionCallbackInfo& args) { @@ -294,6 +308,8 @@ void Initialize(Local target, weak_ref->InstanceTemplate()->SetInternalFieldCount(1); weak_ref->SetClassName(weak_ref_string); env->SetProtoMethod(weak_ref, "get", WeakReference::Get); + env->SetProtoMethod(weak_ref, "incRef", WeakReference::IncRef); + env->SetProtoMethod(weak_ref, "decRef", WeakReference::DecRef); target->Set(context, weak_ref_string, weak_ref->GetFunction(context).ToLocalChecked()).Check(); -- cgit v1.2.3