]> granicus.if.org Git - strace/commitdiff
Add pollhack
authorWichert Akkerman <wichert@deephackmode.org>
Fri, 26 Nov 1999 13:11:29 +0000 (13:11 +0000)
committerWichert Akkerman <wichert@deephackmode.org>
Fri, 26 Nov 1999 13:11:29 +0000 (13:11 +0000)
ChangeLog
README-svr4
strace.c

index c6483c5c2333463080ec5ac369a835447668e5bf..bd679dbc64ce787d818412f6f2c168441716308e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,7 @@ Fri Nov 26 10:51:55 CET 1999 Wichert Akkerman <wakkerma@debian.org>
     + allow net.c to compile on systems without AF_INET6
     + Only use long_to_sigset on Linux systems
     + UnixWare treats sigmask_t and sigmask_t* as the same thing
+    + Add pollhack
 
 Fri Nov 26 01:28:09 CET 1999 Wichert Akkerman <wakkerma@debian.org>
 
index 82febf77cef3e01e61314e0fe84d6ffe89b94c2b..8f66a7fdf4348e429e03b83e948d14666c9bb371 100644 (file)
@@ -16,5 +16,14 @@ on UnixWare 2.1 you need to add the following to config.h yourself:
     #define UNIXWARE 2
     #define HAVE_POLLABLE_PROCFS 1
 
+On UnixWare using the -f option to follow forked children sometimes shows
+many "unfinished" system calls as strace bounces between each runnable child.
+A crude workaround for this is available by adding
+
+    #define POLL_HACK 1
+
+to the config.h file.  This forces strace to check whether the last process
+has finished a system call before polling other processes for events.
+
 Wichert Akkerman <wakkerma@debian.org>
 
index 45390b4d1f85b4d0a24b5c85102df0dcdb6f55ae..f40f5d6348b0e05fc74a7f9a1f124b67f71b9f0d 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -1243,6 +1243,9 @@ choose_pfd()
 static int
 trace()
 {
+#ifdef POLL_HACK
+       struct tcb *in_syscall;
+#endif
        struct tcb *tcp;
        int pfd;
        int what;
@@ -1274,6 +1277,28 @@ trace()
 #endif /* !HAVE_POLLABLE_PROCFS */
                default:
 #ifdef HAVE_POLLABLE_PROCFS
+#ifdef POLL_HACK
+                       /* On some systems (e.g. UnixWare) we get too much ugly
+                          "unfinished..." stuff when multiple proceses are in
+                          syscalls.  Here's a nasty hack */
+                   
+                       if (in_syscall) {
+                               struct pollfd pv;
+                               tcp = in_syscall;
+                               in_syscall = NULL;
+                               pv.fd = tcp->pfd;
+                               pv.events = POLLWANT;
+                               if ((what = poll (&pv, 1, 1)) < 0) {
+                                       if (interrupted)
+                                               return 0;
+                                       continue;
+                               }
+                               else if (what == 1 && pv.revents & POLLWANT) {
+                                       goto FOUND;
+                               }
+                       }
+#endif
+
                        if (poll(pollv, nprocs, INFTIM) < 0) {
                                if (interrupted)
                                        return 0;
@@ -1297,6 +1322,7 @@ trace()
                        fprintf(stderr, "unknown pfd: %u\n", pfd);
                        exit(1);
                }
+       FOUND:
                /* Get the status of the process. */
                if (!interrupted) {
                        ioctl_result = IOCTL_WSTOP (tcp);
@@ -1358,6 +1384,9 @@ trace()
                        }
                        break;
                case PR_SYSENTRY:
+#ifdef POLL_HACK
+                       in_syscall = tcp;
+#endif
                case PR_SYSEXIT:
                        if (trace_syscall(tcp) < 0) {
                                fprintf(stderr, "syscall trouble\n");