]> granicus.if.org Git - strace/commitdiff
Cleanup test_ptrace_setoptions()
authorDmitry V. Levin <ldv@altlinux.org>
Thu, 2 Dec 2010 20:56:43 +0000 (20:56 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 30 Nov 2010 17:19:09 +0000 (17:19 +0000)
* strace.c (test_ptrace_setoptions): Cleanup.
(main): Fix test_ptrace_setoptions() error diagnostics message.
Print ptrace_setoptions value in debug mode.

strace.c

index 6f63ee9a7fa2bcc9feb3e4068fac097330f07f14..fd12b34680a120c2268803c3be00e1d4df42a702 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -689,9 +689,9 @@ startup_child (char **argv)
 
 #ifdef LINUX
 /*
- * Test whether kernel support PTRACE_O_TRACECLONE et al options.
+ * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
  * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
- * and then see which options are supported on this kernel.
+ * and then see which options are supported by the kernel.
  */
 static int
 test_ptrace_setoptions(void)
@@ -701,57 +701,45 @@ test_ptrace_setoptions(void)
        if ((pid = fork()) < 0)
                return -1;
        else if (pid == 0) {
-               if (ptrace(PTRACE_TRACEME, 0, (char *)1, 0) < 0) {
+               if (ptrace(PTRACE_TRACEME, 0, (char *)1, 0) < 0)
                        _exit(1);
-               }
                kill(getpid(), SIGSTOP);
-               if ((pid = fork()) < 0) {
-                       _exit(1);
-               }
-               _exit(0);
+               _exit(fork() < 0);
        }
-       else {
-               int status, tracee_pid, error;
-               int no_child = 0;
-               while (1) {
-                       tracee_pid = wait4(-1, &status, 0, NULL);
-                       error = errno;
-                       if (tracee_pid == -1) {
-                               switch (error) {
-                               case EINTR:
-                                       continue;
-                               case ECHILD:
-                                       no_child = 1;
-                                       break;
-                               default:
-                                       errno = error;
-                                       perror("test_ptrace_setoptions");
-                                       return -1;
-                               }
-                       }
-                       if (no_child)
+
+       while (1) {
+               int status, tracee_pid;
+
+               tracee_pid = wait(&status);
+               if (tracee_pid == -1) {
+                       if (errno == EINTR)
+                               continue;
+                       else if (errno == ECHILD)
                                break;
-                       if (tracee_pid != pid) {
-                               if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0 &&
-                                   errno != ESRCH)
-                                       kill(tracee_pid, SIGKILL);
-                       }
-                       else if (WIFSTOPPED(status)) {
-                               if (status >> 16 == PTRACE_EVENT_FORK)
-                                       ptrace_setoptions |= (PTRACE_O_TRACEVFORK |
-                                                             PTRACE_O_TRACECLONE |
-                                                             PTRACE_O_TRACEFORK);
-                               if (WSTOPSIG(status) == SIGSTOP) {
-                                       if (ptrace(PTRACE_SETOPTIONS, pid, NULL,
-                                                  PTRACE_O_TRACEFORK) < 0) {
-                                               kill(pid, SIGKILL);
-                                               return -1;
-                                       }
-                               }
-                               if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0 &&
-                                   errno != ESRCH)
+                       perror("test_ptrace_setoptions");
+                       return -1;
+               }
+               if (tracee_pid != pid) {
+                       /* the grandchild */
+                       if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0 &&
+                           errno != ESRCH)
+                               kill(tracee_pid, SIGKILL);
+               }
+               else if (WIFSTOPPED(status)) {
+                       if (status >> 16 == PTRACE_EVENT_FORK)
+                               ptrace_setoptions |= (PTRACE_O_TRACEVFORK |
+                                                     PTRACE_O_TRACECLONE |
+                                                     PTRACE_O_TRACEFORK);
+                       if (WSTOPSIG(status) == SIGSTOP) {
+                               if (ptrace(PTRACE_SETOPTIONS, pid, NULL,
+                                          PTRACE_O_TRACEFORK) < 0) {
                                        kill(pid, SIGKILL);
+                                       return -1;
+                               }
                        }
+                       if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0 &&
+                           errno != ESRCH)
+                               kill(pid, SIGKILL);
                }
        }
        return 0;
@@ -988,10 +976,16 @@ main(int argc, char *argv[])
        }
 
 #ifdef LINUX
-       if (followfork && test_ptrace_setoptions() < 0) {
-               fprintf(stderr, "Test for options supported by PTRACE_SETOPTIONS\
-                       failed, give up using this feature\n");
-               ptrace_setoptions = 0;
+       if (followfork) {
+               if (test_ptrace_setoptions() < 0) {
+                       fprintf(stderr,
+                               "Test for options supported by PTRACE_SETOPTIONS "
+                               "failed, giving up using this feature.\n");
+                       ptrace_setoptions = 0;
+               }
+               if (debug)
+                       fprintf(stderr, "ptrace_setoptions = %#x\n",
+                               ptrace_setoptions);
        }
 #endif