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 16cce0df0e2263..e69e4df2b55195 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 baa615e310e17b..aa3fc873943055 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 3d1cc522db380b..96b70b36f2e725 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());