]> granicus.if.org Git - strace/commitdiff
Output format fixes, improving the situation after recent
authorDenys Vlasenko <dvlasenk@redhat.com>
Tue, 6 Jan 2009 21:45:06 +0000 (21:45 +0000)
committerDenys Vlasenko <dvlasenk@redhat.com>
Tue, 6 Jan 2009 21:45:06 +0000 (21:45 +0000)
change which added better handling of processes suddenly
disappearing. Now we often do not finish last line
before exiting in those cases.
The only change affecting something other than output
is change in umovestr where we were calling
abort() on ptrace error.

* strace.c (trace): If trace_syscall() failed with ESRCH,
finish current output line with " <unfinished ...>".
(mp_ioctl): While we are at it, fix gross style mismatch
in this function definition. No code chages.
* syscall.c (trace_syscall): If decode fails on syscall exit,
finish current output line with "= ? <unavailable>".
* util.c (umoven): Do not complain if error is ESRCH.
(umovestr): Do not complain and do not abort() if error is ESRCH.
* defs.h: Remove unused tcp parameter from printtrailer().
* process.c: Adjust printtrailer() calls accordingly.
* strace.c: Adjust printtrailer() calls accordingly.
* syscall.c: Adjust printtrailer() calls accordingly.

ChangeLog
defs.h
process.c
strace.c
syscall.c
util.c

index cdcd920964afa9a8064f7c6f83f77666feae741c..34c2124412061faa170e31471f2f7cb73c31e204 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2009-01-06  Denys Vlasenko  <dvlasenk@redhat.com>
+
+       Output format fixes, improving the situation after recent
+       change which added beeter handling of processes suddenly
+       disappearing. Now we often do not finish last line
+       before exiting in those cases.
+       The only change affecting something other than output
+       is change in umovestr where we were calling
+       abort() on ptrace error.
+
+       * strace.c (trace): If trace_syscall() failed with ESRCH,
+       finish current output line with " <unfinished ...>".
+       (mp_ioctl): While we are at it, fix gross style mismatch
+       in this function definition. No code chages.
+       * syscall.c (trace_syscall): If decode fails on syscall exit,
+       finish current output line with "= ? <unavailable>".
+       * util.c (umoven): Do not complain if error is ESRCH.
+       (umovestr): Do not complain and do not abort() if error is ESRCH.
+       * defs.h: Remove unused tcp parameter from printtrailer().
+       * process.c: Adjust printtrailer() calls accordingly.
+       * strace.c: Adjust printtrailer() calls accordingly.
+       * syscall.c: Adjust printtrailer() calls accordingly.
+
 2009-01-06  Denys Vlasenko  <dvlasenk@redhat.com>
 
        * desc.c (printflock): Fix display of fcntl(F_SETLK) on
diff --git a/defs.h b/defs.h
index e3cd93d0bb86a8e9c04c69f8aa8569496c4c41a0..43c31bc971767889bf468f65371892ce068d443d 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -512,7 +512,7 @@ extern const char *signame P((int));
 extern void print_sigset P((struct tcb *, long, int));
 extern void printsignal P((int));
 extern void printleader P((struct tcb *));
-extern void printtrailer P((struct tcb *));
+extern void printtrailer P((void));
 extern void tabto P((int));
 extern void call_summary P((FILE *));
 extern void tprint_iov P((struct tcb *, unsigned long, unsigned long));
index 02c05959d93db1ebd0cb6b725a27c70b09c3f145..95c47e1d7ac63a26da69d8128534aea4eafe644d 100644 (file)
--- a/process.c
+++ b/process.c
@@ -460,7 +460,7 @@ struct tcb *tcp;
        tprintf("%ld) ", tcp->u_arg[0]);
        tabto(acolumn);
        tprintf("= ?");
-       printtrailer(tcp);
+       printtrailer();
        return 0;
 }
 
index 5c483fe6076ccd334a8225923c7b4ac15371a214..ba23b217f59e1e0f9f79dcf7bc9967a57a5917c8 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -1593,7 +1593,7 @@ int sig;
        }
        else
                catch_sigstop = 1;
-       if (catch_sigstop)
+       if (catch_sigstop) {
                for (;;) {
 #ifdef __WALL
                        if (wait4(tcp->pid, &status, __WALL, NULL) < 0) {
@@ -1637,6 +1637,7 @@ int sig;
                        if (error < 0)
                                break;
                }
+       }
 #endif /* LINUX */
 
 #if defined(SUNOS4)
@@ -1703,8 +1704,8 @@ cleanup()
                                "cleanup: looking at pid %u\n", tcp->pid);
                if (tcp_last &&
                    (!outfname || followfork < 2 || tcp_last == tcp)) {
-                       tprintf(" <unfinished ...>\n");
-                       tcp_last = NULL;
+                       tprintf(" <unfinished ...>");
+                       printtrailer();
                }
                if (tcp->flags & TCB_ATTACHED)
                        detach(tcp, 0);
@@ -2169,13 +2170,13 @@ trace()
                                printleader(tcp);
                                tprintf("--- %s (%s) ---",
                                        signame(what), strsignal(what));
-                               printtrailer(tcp);
+                               printtrailer();
 #ifdef PR_INFO
                                if (tcp->status.PR_INFO.si_signo == what) {
                                        printleader(tcp);
                                        tprintf("    siginfo=");
                                        printsiginfo(&tcp->status.PR_INFO, 1);
-                                       printtrailer(tcp);
+                                       printtrailer();
                                }
 #endif
                        }
@@ -2184,7 +2185,7 @@ trace()
                        if (!cflag && (qual_flags[what] & QUAL_FAULT)) {
                                printleader(tcp);
                                tprintf("=== FAULT %d ===", what);
-                               printtrailer(tcp);
+                               printtrailer();
                        }
                        break;
 #ifdef FREEBSD
@@ -2419,7 +2420,7 @@ Process %d attached (waiting for parent)\n",
                                        WCOREDUMP(status) ? "(core dumped) " :
 #endif
                                        "");
-                               printtrailer(tcp);
+                               printtrailer();
                        }
 #ifdef TCB_GROUP_EXITING
                        handle_group_exit(tcp, -1);
@@ -2608,7 +2609,7 @@ Process %d attached (waiting for parent)\n",
                                tprintf("--- %s (%s) @ %lx (%lx) ---",
                                        signame(WSTOPSIG(status)),
                                        strsignal(WSTOPSIG(status)), pc, addr);
-                               printtrailer(tcp);
+                               printtrailer();
                        }
                        if (((tcp->flags & TCB_ATTACHED) ||
                             tcp->nclone_threads > 0) &&
@@ -2631,9 +2632,24 @@ Process %d attached (waiting for parent)\n",
                if (interrupted)
                        return 0;
                if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) {
-                       if (tcp->flags & TCB_ATTACHED)
+                       /* ptrace() failed in trace_syscall() with ESRCH.
+                        * Likely a result of process disappearing mid-flight.
+                        * Observed case: exit_group() terminating
+                        * all processes in thread group. In this case, threads
+                        * "disappear" in an unpredictable moment without any
+                        * notification to strace via wait().
+                        */
+                       if (tcp->flags & TCB_ATTACHED) {
+                               if (tcp_last) {
+                                       /* Do we have dangling line "syscall(param, param"?
+                                        * Finish the line then. We cannot
+                                        */
+                                       tcp_last->flags |= TCB_REPRINT;
+                                       tprintf(" <unfinished ...>");
+                                       printtrailer();
+                               }
                                detach(tcp, 0);
-                       else {
+                       else {
                                ptrace(PTRACE_KILL,
                                        tcp->pid, (char *) 1, SIGTERM);
                                droptcb(tcp);
@@ -2768,8 +2784,7 @@ int col;
 }
 
 void
-printtrailer(tcp)
-struct tcb *tcp;
+printtrailer(void)
 {
        tprintf("\n");
        tcp_last = NULL;
@@ -2777,8 +2792,9 @@ struct tcb *tcp;
 
 #ifdef HAVE_MP_PROCFS
 
-int mp_ioctl (int fd, int cmd, void *arg, int size) {
-
+int
+mp_ioctl(int fd, int cmd, void *arg, int size)
+{
        struct iovec iov[2];
        int n = 1;
 
@@ -2790,7 +2806,7 @@ int mp_ioctl (int fd, int cmd, void *arg, int size) {
                iov[1].iov_len = size;
        }
 
-       return writev (fd, iov, n);
+       return writev(fd, iov, n);
 }
 
 #endif
index 6fc329e0c36fabb729b0e36863772797b3c490ee..40fd985922dbe5f227bab66b46eccbe6e1a22787 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -2330,6 +2330,9 @@ trace_syscall(struct tcb *tcp)
                if (dtime)
                        gettimeofday(&tv, NULL);
 
+               /* BTW, why we don't just memorize syscall no. on entry
+                * in tcp->something?
+                */
                scno_good = res = get_scno(tcp);
                if (res == 0)
                        return res;
@@ -2368,6 +2371,8 @@ trace_syscall(struct tcb *tcp)
                if (res != 1) {
                        tprintf(") ");
                        tabto(acolumn);
+                       tprintf("= ? <unavailable>");
+                       printtrailer();
                        tcp->flags &= ~TCB_INSYSCALL;
                        return res;
                }
@@ -2466,7 +2471,7 @@ trace_syscall(struct tcb *tcp)
                        tprintf(" <%ld.%06ld>",
                                (long) tv.tv_sec, (long) tv.tv_usec);
                }
-               printtrailer(tcp);
+               printtrailer();
 
                dumpio(tcp);
                if (fflush(tcp->outf) == EOF)
diff --git a/util.c b/util.c
index ac9255136e378a3f2e7c749acc3373749090f196..f9e2b1d8a3760d2158f6c9b76dcfe96c89320da3 100644 (file)
--- a/util.c
+++ b/util.c
@@ -785,13 +785,8 @@ int len;
  * at address `addr' to our space at `laddr'
  */
 int
-umoven(tcp, addr, len, laddr)
-struct tcb *tcp;
-long addr;
-int len;
-char *laddr;
+umoven(struct tcb *tcp, long addr, int len, char *laddr)
 {
-
 #ifdef LINUX
        int pid = tcp->pid;
        int n, m;
@@ -813,7 +808,7 @@ char *laddr;
                                return 0;
                        }
                        /* But if not started, we had a bogus address. */
-                       if (addr != 0 && errno != EIO)
+                       if (addr != 0 && errno != EIO && errno != ESRCH)
                                perror("ptrace: umoven");
                        return -1;
                }
@@ -829,7 +824,7 @@ char *laddr;
                                /* Ran into 'end of memory' - stupid "printpath" */
                                return 0;
                        }
-                       if (addr != 0 && errno != EIO)
+                       if (addr != 0 && errno != EIO && errno != ESRCH)
                                perror("ptrace: umoven");
                        return -1;
                }
@@ -855,7 +850,8 @@ char *laddr;
                errno = 0;
                u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
                if (errno) {
-                       perror("umoven");
+                       if (errno != ESRCH)
+                               perror("umoven");
                        return -1;
                }
                memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
@@ -865,7 +861,8 @@ char *laddr;
                errno = 0;
                u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
                if (errno) {
-                       perror("umoven");
+                       if (errno != ESRCH)
+                               perror("umoven");
                        return -1;
                }
                memcpy(laddr, u.x, m = MIN(sizeof(long), len));
@@ -879,8 +876,10 @@ char *laddr;
                n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
                if (ptrace(PTRACE_READDATA, pid,
                           (char *) addr, len, laddr) < 0) {
-                       perror("umoven: ptrace(PTRACE_READDATA, ...)");
-                       abort();
+                       if (errno != ESRCH) {
+                               perror("umoven: ptrace(PTRACE_READDATA, ...)");
+                               abort();
+                       }
                        return -1;
                }
                len -= n;
@@ -909,11 +908,7 @@ char *laddr;
  * for a terminating zero byte.
  */
 int
-umovestr(tcp, addr, len, laddr)
-struct tcb *tcp;
-long addr;
-int len;
-char *laddr;
+umovestr(struct tcb *tcp, long addr, int len, char *laddr)
 {
 #ifdef USE_PROCFS
 #ifdef HAVE_MP_PROCFS
@@ -964,7 +959,7 @@ char *laddr;
                                /* Ran into 'end of memory' - stupid "printpath" */
                                return 0;
                        }
-                       if (addr != 0 && errno != EIO)
+                       if (addr != 0 && errno != EIO && errno != ESRCH)
                                perror("umovestr");
                        return -1;
                }
@@ -983,7 +978,7 @@ char *laddr;
                                /* Ran into 'end of memory' - stupid "printpath" */
                                return 0;
                        }
-                       if (addr != 0 && errno != EIO)
+                       if (addr != 0 && errno != EIO && errno != ESRCH)
                                perror("umovestr");
                        return -1;
                }