]> granicus.if.org Git - strace/commitdiff
Fix -z display.
authorDenys Vlasenko <dvlasenk@redhat.com>
Mon, 22 Aug 2011 00:06:35 +0000 (02:06 +0200)
committerDenys Vlasenko <dvlasenk@redhat.com>
Tue, 23 Aug 2011 10:53:02 +0000 (12:53 +0200)
Before this patch, the following:
    open("qwerty", O_RDONLY)    = -1 ENOENT
    write(2, "wc: qwerty: No such file or dire"..., 38) = 38
was shown totally wrongly with -z:
    open("qwerty", O_RDONLY)    = 38
(yes, that's right, write syscall is lost!)
Now it is shown "less wrongly" as:
    open("qwerty", O_RDONLY <unfinished ...>
    write(2, "wc: qwerty: No such file or dire"..., 38) = 38

* syscall.c (trace_syscall_exiting): Use common TCB_INSYSCALL clearing
via "goto ret". This fixes totally broken display of -z, but even now
it is not working as intended. Add a comment about that.
(trace_syscall_entering): Use common TCB_INSYSCALL setting
via "goto ret".

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
syscall.c

index a23380491a01bfb7a2fc518ceb9b4ca85d149429..7f7872c0c67a7a61248c1f7f8a52bdd7a9f6dd7f 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -2413,8 +2413,7 @@ trace_syscall_exiting(struct tcb *tcp)
                internal_syscall(tcp);
 
        if (res == 1 && filtered(tcp)) {
-               tcp->flags &= ~TCB_INSYSCALL;
-               return 0;
+               goto ret;
        }
 
        if (tcp->flags & TCB_REPRINT) {
@@ -2433,8 +2432,7 @@ trace_syscall_exiting(struct tcb *tcp)
                struct timeval t = tv;
                count_syscall(tcp, &t);
                if (cflag == CFLAG_ONLY_STATS) {
-                       tcp->flags &= ~TCB_INSYSCALL;
-                       return 0;
+                       goto ret;
                }
        }
 
@@ -2451,14 +2449,22 @@ trace_syscall_exiting(struct tcb *tcp)
            || (qual_flags[tcp->scno] & QUAL_RAW))
                sys_res = printargs(tcp);
        else {
+       /* FIXME: not_failing_only (IOW, option -z) is broken:
+        * failure of syscall is known only after syscall return.
+        * Thus we end up with something like this on, say, ENOENT:
+        *     open("doesnt_exist", O_RDONLY <unfinished ...>
+        *     {next syscall decode}
+        * whereas the intended result is that open(...) line
+        * is not shown at all.
+        */
                if (not_failing_only && tcp->u_error)
-                       return 0;       /* ignore failed syscalls */
+                       goto ret;       /* ignore failed syscalls */
                sys_res = (*sysent[tcp->scno].sys_func)(tcp);
        }
 
-       u_error = tcp->u_error;
        tprintf(") ");
        tabto(acolumn);
+       u_error = tcp->u_error;
        if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
            qual_flags[tcp->scno] & QUAL_RAW) {
                if (u_error)
@@ -2546,6 +2552,7 @@ trace_syscall_exiting(struct tcb *tcp)
        dumpio(tcp);
        if (fflush(tcp->outf) == EOF)
                return -1;
+ ret:
        tcp->flags &= ~TCB_INSYSCALL;
        return 0;
 }
@@ -2553,7 +2560,6 @@ trace_syscall_exiting(struct tcb *tcp)
 static int
 trace_syscall_entering(struct tcb *tcp)
 {
-       int sys_res;
        int res, scno_good;
 
        scno_good = res = get_scno(tcp);
@@ -2582,8 +2588,7 @@ trace_syscall_entering(struct tcb *tcp)
                 * " <unavailable>" will be added later by the code which
                 * detects ptrace errors.
                 */
-               tcp->flags |= TCB_INSYSCALL;
-               return res;
+               goto ret;
        }
 
        switch (known_scno(tcp)) {
@@ -2686,9 +2691,8 @@ trace_syscall_entering(struct tcb *tcp)
        tcp->flags &= ~TCB_FILTERED;
 
        if (cflag == CFLAG_ONLY_STATS) {
-               tcp->flags |= TCB_INSYSCALL;
-               gettimeofday(&tcp->etime, NULL);
-               return 0;
+               res = 0;
+               goto ret;
        }
 
        printleader(tcp);
@@ -2701,16 +2705,18 @@ trace_syscall_entering(struct tcb *tcp)
        if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
            ((qual_flags[tcp->scno] & QUAL_RAW) &&
             sysent[tcp->scno].sys_func != sys_exit))
-               sys_res = printargs(tcp);
+               res = printargs(tcp);
        else
-               sys_res = (*sysent[tcp->scno].sys_func)(tcp);
+               res = (*sysent[tcp->scno].sys_func)(tcp);
+
        if (fflush(tcp->outf) == EOF)
                return -1;
+ ret:
        tcp->flags |= TCB_INSYSCALL;
        /* Measure the entrance time as late as possible to avoid errors. */
        if (dtime || cflag)
                gettimeofday(&tcp->etime, NULL);
-       return sys_res;
+       return res;
 }
 
 int