]> granicus.if.org Git - strace/commitdiff
detach(): warn if we see ECHILD from waitpid
authorDenys Vlasenko <dvlasenk@redhat.com>
Thu, 20 Jun 2013 10:10:21 +0000 (12:10 +0200)
committerDenys Vlasenko <dvlasenk@redhat.com>
Thu, 20 Jun 2013 13:34:12 +0000 (15:34 +0200)
* 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 <dvlasenk@redhat.com>
strace.c

index ae24db12f420ab2e8a053a14e9b63636cf3190a1..89e89bc3a534695a6e4a20a5a2da98a123b0d385 100644 (file)
--- 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;
+                       }
                }
        }