From 43781fb97c4357a44399af56fd9cea39f680458d Mon Sep 17 00:00:00 2001 From: jakecastelli Date: Fri, 14 Mar 2025 17:34:42 +1030 Subject: [PATCH] src: force gc for flaky (deadlock) tests This patch adds a new flag `force_gc_for_test` (internal use for test purpose only) to force GC specifically for flaky tests that suffer from deadlock. The deadlock occurs when: 1. Main thread calls DrainTasks and executes worker tasks 2. Worker task needs memory allocation requiring GC 3. GC must run on main thread, but main thread is busy running the worker task --- src/node_options.cc | 4 ++++ src/node_options.h | 1 + src/node_platform.cc | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/src/node_options.cc b/src/node_options.cc index 16cce0df0e2..e69e4df2b55 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -1166,6 +1166,10 @@ PerProcessOptionsParser::PerProcessOptionsParser( "force FIPS crypto (cannot be disabled)", &PerProcessOptions::force_fips_crypto, kAllowedInEnvvar); + AddOption("--force-gc-for-test", + "", + &PerProcessOptions::force_gc_for_test, + kAllowedInEnvvar); AddOption("--secure-heap", "total size of the OpenSSL secure heap", &PerProcessOptions::secure_heap, diff --git a/src/node_options.h b/src/node_options.h index baa615e310e..aa3fc873943 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -321,6 +321,7 @@ class PerProcessOptions : public Options { std::string snapshot_blob; std::vector security_reverts; + bool force_gc_for_test = false; bool print_bash_completion = false; bool print_help = false; bool print_v8_help = false; diff --git a/src/node_platform.cc b/src/node_platform.cc index 3d1cc522db3..96b70b36f2e 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -464,6 +464,11 @@ void NodePlatform::DrainTasks(Isolate* isolate) { if (!per_isolate) return; do { + if (per_process::cli_options->force_gc_for_test) { + isolate->RequestGarbageCollectionForTesting( + Isolate::GarbageCollectionType::kFullGarbageCollection); + } + // Worker tasks aren't associated with an Isolate. worker_thread_task_runner_->BlockingDrain(); } while (per_isolate->FlushForegroundTasksInternal());