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);
}
};