]> granicus.if.org Git - strace/commitdiff
Fix botched commit.
authorRoland McGrath <roland@redhat.com>
Mon, 16 Dec 2002 20:42:50 +0000 (20:42 +0000)
committerRoland McGrath <roland@redhat.com>
Mon, 16 Dec 2002 20:42:50 +0000 (20:42 +0000)
strace.c

index ea9439bbb318e78382ac3bde8ff9a6fea42357ae..ec8d752717b16c7d493fad70115656d6ca4b9e43 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -1042,110 +1042,58 @@ int sig;
 #ifdef LINUX
        /*
         * Linux wrongly insists the child be stopped
-        * before detaching.  This creates numerous headaches
-        * as the process we are tracing may be running.
-        *
-        * First try to simply detach from the process; if it was
-        * already stopped, this will succeed and we're done.
-        *
-        * Otherwise stop the process by sending it a SIGSTOP
-        * signal.
-        *
-        * Once the process is stopped we have to make sure it
-        * received the SIGSTOP (it may have received a SIGTRAP or
-        * other signal).  If it did not receive the SIGSTOP, 
-        * restart the process and try again. 
-        *
-        * Once stopped with a SIGSTOP, we can detach from the
-        * process via PTRACE_DETACH. 
-        *
+        * before detaching.  Arghh.  We go through hoops
+        * to make a clean break of things.
         */
-       
+#if defined(SPARC)
+#undef PTRACE_DETACH
+#define PTRACE_DETACH PTRACE_SUNDETACH
+#endif
        if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) == 0) {
                /* On a clear day, you can see forever. */
-       } else {
-
+       }
+       else if (errno != ESRCH) {
+               /* Shouldn't happen. */
+               perror("detach: ptrace(PTRACE_DETACH, ...)");
+       }
+       else if (kill(tcp->pid, 0) < 0) {
+               if (errno != ESRCH)
+                       perror("detach: checking sanity");
+       }
+       else if (kill(tcp->pid, SIGSTOP) < 0) {
+               if (errno != ESRCH)
+                       perror("detach: stopping child");
+       }
+       else {
                for (;;) {
-                       if (kill(tcp->pid, 0) < 0) {
-                               if (errno != ESRCH)
-                                       perror("detach: checking sanity");
-                       }
-                       else if (kill(tcp->pid, SIGSTOP) < 0) {
-                               if (errno != ESRCH)
-                               perror("detach: stopping child");
-                       }
-       
-                       /*
-                       * At this point the child should be stopped.  Try to
-                       * wait on it so we can get its stop status.  Use WNOHANG
-                       * to avoid this wait hanging.
-                       */
-                       if (waitpid (tcp->pid, &status, (WUNTRACED | WNOHANG)) < 0) {
-                               if (errno != ECHILD) {
+                       if (waitpid(tcp->pid, &status, 0) < 0) {
+                               if (errno != ECHILD)
                                        perror("detach: waiting");
-                               } else {
-       
-                                       /*
-                                       * Try again, this time with the __WCLONE
-                                       * flag.  Note we may get notifications
-                                       * for other processes/threads!
-                                       */
-                                       errno = 0;
-                                       while (1) {
-                                               int x;
-
-                                               x = waitpid (-1, &status, __WCLONE);
-                                               if (x == tcp->pid || x < 0 || errno != 0)
-                                                       break;
-                                       }
-                               }
-       
-                               if (errno) {
-                                       perror ("Unable to wait on inferior");
-                                       return -1;
-                               }
+                               break;
                        }
-                       
-                       /*
-                       * At this point we have wait status for the
-                       * inferior.  If it did not stop, then all 
-                       * bets are off.
-                       */
                        if (!WIFSTOPPED(status)) {
                                /* Au revoir, mon ami. */
                                break;
                        }
-       
-                       /*
-                       * If the process/thread has stopped with a
-                       * SIGSTOP, then we can continue and detach
-                       * with PTRACE_DETACH.
-                       */
                        if (WSTOPSIG(status) == SIGSTOP) {
                                if ((error = ptrace(PTRACE_DETACH,
-                               tcp->pid, (char *) 1, sig)) < 0) {
+                                   tcp->pid, (char *) 1, sig)) < 0) {
                                        if (errno != ESRCH)
                                                perror("detach: ptrace(PTRACE_DETACH, ...)");
                                        /* I died trying. */
                                }
                                break;
                        }
-       
-                       /*
-                       * The process/thread did not stop with a SIGSTOP,
-                       * so let it continue and try again to stop it with
-                       * a SIGSTOP.
-                       */
                        if ((error = ptrace(PTRACE_CONT, tcp->pid, (char *) 1,
-                       WSTOPSIG(status) == SIGTRAP ?
-                       0 : WSTOPSIG(status))) < 0) {
+                           WSTOPSIG(status) == SIGTRAP ?
+                           0 : WSTOPSIG(status))) < 0) {
                                if (errno != ESRCH)
                                        perror("detach: ptrace(PTRACE_CONT, ...)");
                                break;
                        }
                }
        }
-#endif
+#endif /* LINUX */
 
 #if defined(SUNOS4)
        /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */