From 2b0315fd5e5763e09d3859fb4cfa0ad39e69efa5 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 28 Mar 2020 01:14:06 +0100 Subject: [PATCH] src: flush V8 interrupts from Environment dtor This avoids an edge-case memory leak. Refs: https://github.com/nodejs/node/pull/32523#discussion_r399554491 PR-URL: https://github.com/nodejs/node/pull/32523 Reviewed-By: Matheus Marchini Reviewed-By: James M Snell --- src/env.cc | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/env.cc b/src/env.cc index 4f1ffbd7400f43..703a2a15758f95 100644 --- a/src/env.cc +++ b/src/env.cc @@ -41,11 +41,13 @@ using v8::NewStringType; using v8::Number; using v8::Object; using v8::Private; +using v8::Script; using v8::SnapshotCreator; using v8::StackTrace; using v8::String; using v8::Symbol; using v8::TracingController; +using v8::TryCatch; using v8::Undefined; using v8::Value; using worker::Worker; @@ -412,11 +414,30 @@ Environment::Environment(IsolateData* isolate_data, } Environment::~Environment() { - if (Environment** interrupt_data = interrupt_data_.load()) + if (Environment** interrupt_data = interrupt_data_.load()) { + // There are pending RequestInterrupt() callbacks. Tell them not to run, + // then force V8 to run interrupts by compiling and running an empty script + // so as not to leak memory. *interrupt_data = nullptr; - // FreeEnvironment() should have set this. - CHECK(is_stopping()); + Isolate::AllowJavascriptExecutionScope allow_js_here(isolate()); + HandleScope handle_scope(isolate()); + TryCatch try_catch(isolate()); + Context::Scope context_scope(context()); + +#ifdef DEBUG + bool consistency_check = false; + isolate()->RequestInterrupt([](Isolate*, void* data) { + *static_cast(data) = true; + }, &consistency_check); +#endif + + Local