From d2e1f42d8a28486484f00739e561a58be4808b03 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 8 Jul 2013 11:28:27 +0200 Subject: [PATCH] Exit trace loop if got ECHILD, not if nprocs == 0. Comment gives a testcase which wasn't handled correctly by the old code. Signed-off-by: Denys Vlasenko --- strace.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/strace.c b/strace.c index a489db43..abaa463b 100644 --- a/strace.c +++ b/strace.c @@ -1964,7 +1964,17 @@ trace(void) { struct rusage ru; - while (nprocs != 0) { + /* Used to be "while (nprocs != 0)", but in this testcase: + * int main() { _exit(!!fork()); } + * under strace -f, parent sometimes (rarely) manages + * to exit before we see the first stop of the child, + * and we are losing track of it: + * 19923 clone(...) = 19924 + * 19923 exit_group(1) = ? + * 19923 +++ exited with 1 +++ + * Waiting for ECHILD works better. + */ + while (1) { int pid; int wait_errno; int status, sig; @@ -1985,9 +1995,11 @@ trace(void) if (pid < 0) { if (wait_errno == EINTR) continue; - if (wait_errno == ECHILD) - /* Should not happen since nprocs > 0 */ + if (nprocs == 0 && wait_errno == ECHILD) return; + /* If nprocs > 0, ECHILD is not expected, + * treat it as any other error here: + */ errno = wait_errno; perror_msg_and_die("wait4(__WALL)"); } -- 2.40.0