2007-09-22  Alan Curry <[EMAIL PROTECTED]>
            Dmitry V. Levin <[EMAIL PROTECTED]>

        * stream.c (decode_poll): Rearrange so that arguments are decoded
        and printed on syscall entry, except for revents and the output
        timespec which are now printed in the auxstr.
        (sys_poll): Print the input timeout argument on syscall entry.
        [LINUX] (sys_ppoll): Likewise.

--- a/strace/stream.c
+++ b/strace/stream.c
@@ -297,69 +297,152 @@ static const struct xlat pollflags[] = {
 };
 
 static int
-decode_poll(struct tcb *tcp)
+decode_poll(struct tcb *tcp, long pts)
 {
        struct pollfd fds;
        unsigned nfds;
        unsigned long size, start, cur, end, abbrev_end;
        int failed = 0;
 
-       if (entering(tcp))
-               return 0;
-
-       nfds = tcp->u_arg[1];
-       size = sizeof(fds) * nfds;
-       start = tcp->u_arg[0];
-       end = start + size;
-       if (nfds == 0 || size / sizeof(fds) != nfds || end < start) {
-               tprintf("%#lx, %d, ",
-                       tcp->u_arg[0], nfds);
-               return 0;
-       }
-       if (abbrev(tcp)) {
-               abbrev_end = start + max_strlen * sizeof(fds);
-               if (abbrev_end < start)
+       if (entering(tcp)) {
+               nfds = tcp->u_arg[1];
+               size = sizeof(fds) * nfds;
+               start = tcp->u_arg[0];
+               end = start + size;
+               if (nfds == 0 || size / sizeof(fds) != nfds || end < start) {
+                       tprintf("%#lx, %d, ",
+                               tcp->u_arg[0], nfds);
+                       return 0;
+               }
+               if (abbrev(tcp)) {
+                       abbrev_end = start + max_strlen * sizeof(fds);
+                       if (abbrev_end < start)
+                               abbrev_end = end;
+               } else {
                        abbrev_end = end;
+               }
+               tprintf("[");
+               for (cur = start; cur < end; cur += sizeof(fds)) {
+                       if (cur > start)
+                               tprintf(", ");
+                       if (cur >= abbrev_end) {
+                               tprintf("...");
+                               break;
+                       }
+                       if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
+                               tprintf("?");
+                               failed = 1;
+                               break;
+                       }
+                       if (fds.fd < 0) {
+                               tprintf("{fd=%d}", fds.fd);
+                               continue;
+                       }
+                       tprintf("{fd=%d, events=", fds.fd);
+                       printflags(pollflags, fds.events, "POLL???");
+                       tprintf("}");
+               }
+               tprintf("]");
+               if (failed)
+                       tprintf(" %#lx", start);
+               tprintf(", %d, ", nfds);
+               return 0;
        } else {
-               abbrev_end = end;
-       }
-       tprintf("[");
-       for (cur = start; cur < end; cur += sizeof(fds)) {
-               if (cur > start)
-                       tprintf(", ");
-               if (cur >= abbrev_end) {
-                       tprintf("...");
-                       break;
+               static char outstr[1024];
+               char str[64];
+                const char *flagstr;
+               unsigned int cumlen;
+
+               if (syserror(tcp))
+                       return 0;
+               if (tcp->u_rval == 0) {
+                       tcp->auxstr = "Timeout";
+                       return RVAL_STR;
                }
-               if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
-                       tprintf("?");
-                       failed = 1;
-                       break;
+
+               nfds = tcp->u_arg[1];
+               size = sizeof(fds) * nfds;
+               start = tcp->u_arg[0];
+               end = start + size;
+               if (nfds == 0 || size / sizeof(fds) != nfds || end < start)
+                       return 0;
+               if (abbrev(tcp)) {
+                       abbrev_end = start + max_strlen * sizeof(fds);
+                       if (abbrev_end < start)
+                               abbrev_end = end;
+               } else {
+                       abbrev_end = end;
                }
-               if (fds.fd < 0) {
-                       tprintf("{fd=%d}", fds.fd);
-                       continue;
+
+               outstr[0] = '\0';
+               cumlen = 0;
+
+               for (cur = start; cur < end; cur += sizeof(fds)) {
+                       if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
+                               ++cumlen;
+                               if (cumlen < sizeof(outstr))
+                                       strcat(outstr, "?");
+                               failed = 1;
+                               break;
+                       }
+                       if (!fds.revents)
+                               continue;
+                       if (!cumlen) {
+                               ++cumlen;
+                               strcat(outstr, "[");
+                       } else {
+                               cumlen += 2;
+                               if (cumlen < sizeof(outstr))
+                                       strcat(outstr, ", ");
+                       }
+                       if (cur >= abbrev_end) {
+                               cumlen += 3;
+                               if (cumlen < sizeof(outstr))
+                                       strcat(outstr, "...");
+                               break;
+                       }
+                       sprintf(str, "{fd=%d, revents=", fds.fd);
+                       flagstr=sprintflags("", pollflags, fds.revents);
+                       cumlen += strlen(str) + strlen(flagstr) + 1;
+                       if (cumlen < sizeof(outstr)) {
+                               strcat(outstr, str);
+                               strcat(outstr, flagstr);
+                               strcat(outstr, "}");
+                       }
                }
-               tprintf("{fd=%d, events=", fds.fd);
-               printflags(pollflags, fds.events, "POLL???");
-               if (!syserror(tcp) && fds.revents) {
-                       tprintf(", revents=");
-                       printflags(pollflags, fds.revents, "POLL???");
+               if (failed)
+                       return 0;
+
+               if (cumlen && ++cumlen < sizeof(outstr))
+                       strcat(outstr, "]");
+
+               if (pts) {
+                       struct timespec ts;
+                       char str[128];
+
+                       sprintf(str, "%sleft ", cumlen ? ", " : "");
+                       if (umove(tcp, pts, &ts) == 0)
+                               sprintf(str + strlen(str), "{%lu, %lu}",
+                                       ts.tv_sec, ts.tv_nsec);
+                       else
+                               strcat(str, "{...}");
+                       if ((cumlen += strlen(str)) < sizeof(outstr))
+                               strcat(outstr, str);
                }
-               tprintf("}");
+
+               if (!outstr[0])
+                       return 0;
+
+               tcp->auxstr = outstr;
+               return RVAL_STR;
        }
-       tprintf("]");
-       if (failed)
-               tprintf(" %#lx", start);
-       tprintf(", %d, ", nfds);
-       return 0;
 }
 
 int
 sys_poll(struct tcb *tcp)
 {
-       int rc = decode_poll(tcp);
-       if (exiting(tcp)) {
+       int rc = decode_poll(tcp, 0);
+       if (entering(tcp)) {
 #ifdef INFTIM
                if (tcp->u_arg[2] == INFTIM)
                        tprintf("INFTIM");
@@ -374,8 +457,8 @@ sys_poll(struct tcb *tcp)
 int
 sys_ppoll(struct tcb *tcp)
 {
-       int rc = decode_poll(tcp);
-       if (exiting(tcp)) {
+       int rc = decode_poll(tcp, tcp->u_arg[2]);
+       if (entering(tcp)) {
                struct timespec ts;
                if (umove(tcp, tcp->u_arg[2], &ts) == 0)
                        tprintf("{%lu, %lu}, ", ts.tv_sec, ts.tv_nsec);

-- 
ldv

Attachment: pgpZ7h3NGcaOE.pgp
Description: PGP signature

Reply via email to