You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[os x] killing freshly started processes is unreliable #1226
Sending a SIGTERM to a process that is still starting up kills it with SIGKILL on my OS X machine, not SIGTERM. It's making the kill test fail reliably for me locally.
$ uname -a
Darwin hermes.local 16.4.0 Darwin Kernel Version 16.4.0: Thu Dec 22 22:53:21 PST 2016; root:xnu-3789.41.3~3/RELEASE_X86_64 x86_64
$ out/Debug/run-tests kill
not ok 1 - kill
# exit code 6
# Output from process `kill`:
# exit_cb
# no_term_signal=0 term_signal=9 exit_status=0
# Assertion failed in ../test/test-spawn.c on line 95: no_term_signal || term_signal == 15
Adding a small delay avoids it:
diff --git a/test/test-spawn.c b/test/test-spawn.c
index 53a0369..6676101 100644
--- a/test/test-spawn.c+++ b/test/test-spawn.c@@ -920,6 +922,7 @@ TEST_IMPL(kill) {
r = uv_spawn(uv_default_loop(), &process, &options);
ASSERT(r == 0);
+ usleep(1000);
/* Sending signum == 0 should check if the
* child process is still alive, not kill it.
Interestingly, sending a different signal works okay too (SIGINT here but e.g. SIGQUIT works too):
FWIW, I see this failure occasionally in the node test suite too now:
=== release test-child-process-exec-timeout ===
Path: parallel/test-child-process-exec-timeout
assert.js:85
throw new assert.AssertionError({
^
AssertionError: 'SIGKILL' === 'SIGTERM'
at cp.exec.common.mustCall (/Users/bnoordhuis/src/v1.x/test/parallel/test-child-process-exec-timeout.js:21:10)
at /Users/bnoordhuis/src/v1.x/test/common.js:446:15
at ChildProcess.exithandler (child_process.js:238:5)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:194:7)
at maybeClose (internal/child_process.js:892:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
Command: out/Release/node /Users/bnoordhuis/src/v1.x/test/parallel/test-child-process-exec-timeout.js
The test sends a SIGTERM one millisecond after spawning the child. It doesn't fail as reliably as the libuv test suite but fail it does.
For a company that purports to have "It Just Works" as their motto, Apple has an amazing propensity for screwing up their operating system more with every update.
Anyone have suggestions on how to handle this? Just tweak the test suites and move on? I'd worry we'd be making it less flaky but not not flaky.
What about allowing SIGKILL as an acceptable signal only for OS X with an explaining comment? Even we could only allow it for some OS X specific version / range so we know when / if it is fixed?
@gibfahn I've modified your code a little to make it more similar to how that's implemented. Still, it does not reproduce the issue we see on the test...
#include<stdio.h>#include<unistd.h>#include<signal.h>#include<sys/wait.h>#include<assert.h>voidcatcher(intsig) {
// SIGCHLD handler. It should print when child process dies. In libuv, the main process// is notified by writing to a pipe when this signal is received.printf("Caught: %i (%X)\n", sig, sig);
}
intmain() {
printf("SIGKILL: %i (%X)\n", SIGKILL, SIGKILL);
printf("SIGTERM: %i (%X)\n", SIGTERM, SIGTERM);
signal(SIGCHLD, catcher);
intstatus;
intpid=fork();
if (pid==0) {
printf("ok child\n");
} else {
intstatus=kill(pid, SIGTERM);
printf("Parent: child pid: %i (0x%X)\n", pid, pid);
printf("Parent: kill status: %i\n", status);
// wait a little so the child process dies.sleep(1);
// In libuv this is executed when the SIGCHLD notification is receivedintpid2=waitpid(pid, &status, WNOHANG);
assert(pid==pid2);
if (WIFEXITED(status))
fprintf(stderr, "Exit with status: %d\n", WEXITSTATUS(status));
if (WIFSIGNALED(status))
fprintf(stderr, "Exit with signal: %d\n", WTERMSIG(status));
}
}
Activity
saghul commentedon Feb 15, 2017
Does this just happen on macOS? If so we can add the
usleepsurrounded with an ifdef and a comment, maybe?bnoordhuis commentedon Feb 15, 2017
It doesn't happen on any of my Linux machines and I think it didn't happen on my MBA either before the latest Apple update.
bnoordhuis commentedon Feb 17, 2017
FWIW, I see this failure occasionally in the node test suite too now:
The test sends a SIGTERM one millisecond after spawning the child. It doesn't fail as reliably as the libuv test suite but fail it does.
santigimeno commentedon Feb 23, 2017
FWIW, the test fails in my
OS Xtoo. It fails like 5% of the time.bnoordhuis commentedon Feb 24, 2017
For a company that purports to have "It Just Works" as their motto, Apple has an amazing propensity for screwing up their operating system more with every update.
Anyone have suggestions on how to handle this? Just tweak the test suites and move on? I'd worry we'd be making it less flaky but not not flaky.
santigimeno commentedon Feb 24, 2017
What about allowing
SIGKILLas an acceptable signal only forOS Xwith an explaining comment? Even we could only allow it for someOS Xspecific version / range so we know when / if it is fixed?gibfahn commentedon Feb 24, 2017
This seems like something that should be raised against macOS, but I have no idea how that is done.
Maybe https://developer.apple.com/bug-reporting/ ?
bnoordhuis commentedon Feb 24, 2017
Don't bother, Apple never seems to act on, or even acknowledge, bug reports.
That seems reasonable.
saghul commentedon Feb 27, 2017
SGTM.
santigimeno commentedon Apr 1, 2017
After the latest
OS Xupdate this got worse. It's failing 100% of the time. I'll create a PR.test,osx: fix flaky kill test
gibfahn commentedon Apr 2, 2017
I was trying to create a minimal C reproduction of this (partly to learn about how this all works), so far I'm on:
Running with:
clang -O3 test.c && ./a.out, I always get:I assume I'm missing something.
I also ran with
dtruss, but the kill syscall is always0xF.dtruss output:
santigimeno commentedon Apr 2, 2017
@gibfahn I've modified your code a little to make it more similar to how that's implemented. Still, it does not reproduce the issue we see on the test...
bnoordhuis commentedon Apr 3, 2017
@gibfahn @santigimeno The test only forks, it doesn't execve like libuv does.
santigimeno commentedon Apr 3, 2017
@bnoordhuis thanks for clearing that up.
test,osx: fix flaky kill test
test,osx: fix flaky kill test
test: fix flaky test-child-process-exec-timeout
test: fix flaky test-child-process-exec-timeout
test: fix flaky test-child-process-exec-timeout
test: fix flaky test-child-process-exec-timeout
test: fix flaky test-child-process-exec-timeout