Commit 929b39c85bc for nodejs

commit 929b39c85bc5245118e808fd409405295773005c
Author: Filip Skokan <panva.ip@gmail.com>
Date:   Sat Sep 26 15:37:50 2026 +0200

    test: probe cluster workers with signal 0

    common.isAlive() sends SIGCONT while polling exiting workers. On Linux,
    this can discard a pending SIGSTOP from LeakSanitizer's ptrace attach,
    leaving its thread-suspension loop waiting indefinitely.

    Use signal 0 to check existence without changing the process state.
    This also makes the liveness check work on Windows, where SIGCONT is
    unsupported. Treat only ESRCH as a dead process and propagate other
    errors. Remove the ASan flaky expectation.

    Refs: https://github.com/nodejs/node/issues/39655
    Signed-off-by: Filip Skokan <panva.ip@gmail.com>
    Assisted-by: Claude, Codex
    PR-URL: https://github.com/nodejs/node/pull/66320
    Reviewed-By: James M Snell <jasnell@gmail.com>
    Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>

diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status
index 77ec92bc5d9..3c26a14cd47 100644
--- a/test/parallel/parallel.status
+++ b/test/parallel/parallel.status
@@ -123,10 +123,6 @@ test-tls-set-default-ca-certificates-append-fetch: SKIP
 test-tls-set-default-ca-certificates-reset-fetch: SKIP
 test-inspector-invalid-protocol: SKIP

-[$asan==on]
-# https://github.com/nodejs/node/issues/39655
-test-cluster-primary-error: PASS, FLAKY
-
 [$arch==loong64]
 # https://github.com/nodejs/node/issues/51662
 test-http-correct-hostname: SKIP
diff --git a/test/parallel/test-cluster-primary-error.js b/test/parallel/test-cluster-primary-error.js
index 232de51f29f..f9ebdc4c85d 100644
--- a/test/parallel/test-cluster-primary-error.js
+++ b/test/parallel/test-cluster-primary-error.js
@@ -88,12 +88,24 @@ if (cluster.isWorker) {
     // Check that the cluster died accidentally (non-zero exit code)
     assert.strictEqual(code, 1);

+    // Probe with signal 0. common.isAlive() sends SIGCONT, which discards the
+    // pending SIGSTOP that LeakSanitizer's exit-time stop-the-world waits for
+    // under ASan on Linux, leaving the exiting worker hung forever.
+    const isAlive = (pid) => {
+      try {
+        return process.kill(pid, 0);
+      } catch (err) {
+        if (err.code !== 'ESRCH') throw err;
+        return false;
+      }
+    };
+
     // XXX(addaleax): The fact that this uses raw PIDs makes the test inherently
     // flaky – another process might end up being started right after the
     // workers finished and receive the same PID.
     const pollWorkers = () => {
       // When primary is dead all workers should be dead too
-      if (workers.some((pid) => common.isAlive(pid))) {
+      if (workers.some(isAlive)) {
         setTimeout(pollWorkers, 50);
       }
     };