From: Denys Vlasenko Date: Thu, 20 Jun 2013 10:10:21 +0000 (+0200) Subject: detach(): warn if we see ECHILD from waitpid X-Git-Tag: v4.9~231 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fdfa47af7e05b320cc1c62fc5854ded781679917;p=strace detach(): warn if we see ECHILD from waitpid * strace.c (detach): Warn if we see ECHILD from waitpid. Explain in comments that we don't normally expect !WIFSTOPPED either, and also that PTRACE_CONT failure isn't expected (the "break" there is a "I'm confused, bailing out" code style).. Signed-off-by: Denys Vlasenko --- diff --git a/strace.c b/strace.c index ae24db12..89e89bc3 100644 --- a/strace.c +++ b/strace.c @@ -764,7 +764,7 @@ detach(struct tcb *tcp) } else if (errno != ESRCH) { /* Shouldn't happen. */ - perror_msg("detach: ptrace(%u,PTRACE_DETACH)", tcp->pid); + perror_msg("detach: ptrace(PTRACE_DETACH,%u)", tcp->pid); } else /* ESRCH: process is either not stopped or doesn't exist. */ @@ -789,7 +789,7 @@ detach(struct tcb *tcp) if (!error) interrupt_done = 1; else if (errno != ESRCH) - perror_msg("detach: ptrace(%u,PTRACE_INTERRUPT)", tcp->pid); + perror_msg("detach: ptrace(PTRACE_INTERRUPT,%u)", tcp->pid); } else { error = my_tkill(tcp->pid, SIGSTOP); @@ -807,13 +807,25 @@ detach(struct tcb *tcp) if (waitpid(tcp->pid, &status, __WALL) < 0) { if (errno == EINTR) continue; - if (errno == ECHILD) /* Already gone. */ - break; + /* + * if (errno == ECHILD) break; + * ^^^ WRONG! We expect this PID to exist, + * and want to emit a message otherwise: + */ perror_msg("detach: waitpid(%u)", tcp->pid); break; } if (!WIFSTOPPED(status)) { - /* Au revoir, mon ami. */ + /* + * Tracee exited or was killed by signal. + * We shouldn't normally reach this place: + * we don't want to consume exit status. + * Consider "strace -p PID" being ^C-ed: + * we want merely to detach from PID. + * + * However, we _can_ end up here if tracee + * was SIGKILLed. + */ break; } sig = WSTOPSIG(status); @@ -859,8 +871,13 @@ detach(struct tcb *tcp) sig = 0; /* Can't detach just yet, may need to wait for SIGSTOP */ error = ptrace_restart(PTRACE_CONT, tcp, sig); - if (error < 0) + if (error < 0) { + /* Should not happen. + * Note: ptrace_restart returns 0 on ESRCH, so it's not it. + * ptrace_restart already emitted error message. + */ break; + } } }