> Patch 3: Split TCB_STARTUP into TCB_STARTUP and TCB_IGNORE_ONE_SIGSTOP
> bits. This is required by SIEZE because with SIEZE, waiting for SIGSTOP
> is not necessary, but initialization is still needed.

diff -d -urpN strace.3/defs.h strace.4/defs.h
--- strace.3/defs.h     2011-09-01 20:17:13.712850718 +0200
+++ strace.4/defs.h     2011-09-02 11:23:45.242545628 +0200
@@ -436,8 +436,15 @@ struct tcb {
 };
 
 /* TCB flags */
-#define TCB_STARTUP    00001   /* We have just begun ptracing this process */
-#define TCB_INUSE      00002   /* This table entry is in use */
+#define TCB_INUSE              00001   /* This table entry is in use */
+/* We have attached to this process, but did not see it stopping yet.
+ * (If this bit is not set, we either didn't attach yet,
+ * or we did attach to it, already saw it stopping at least once,
+ * did some init work on it and cleared this bit. TODO: maybe it makes sense
+ * to split these two states?)
+ */
+#define TCB_STARTUP            00002
+#define TCB_IGNORE_ONE_SIGSTOP 00004   /* Next SIGSTOP is to be ignored */
 /*
  * Are we in system call entry or in syscall exit?
  *
@@ -456,8 +463,8 @@ struct tcb {
  *
  * Use entering(tcp) / exiting(tcp) to check this bit to make code more 
readable.
  */
-#define TCB_INSYSCALL  00004
-#define TCB_ATTACHED   00010   /* Process is not our own child */
+#define TCB_INSYSCALL  00010
+#define TCB_ATTACHED   00020   /* Process is not our own child */
 #define TCB_BPTSET     00100   /* "Breakpoint" set after fork(2) */
 #define TCB_SIGTRAPPED 00200   /* Process wanted to block SIGTRAP */
 #define TCB_REPRINT    01000   /* We should reprint this syscall on exit */
diff -d -urpN strace.3/process.c strace.4/process.c
--- strace.3/process.c  2011-09-01 18:30:57.848409673 +0200
+++ strace.4/process.c  2011-09-02 11:38:20.129919984 +0200
@@ -859,7 +859,7 @@ internal_fork(struct tcb *tcp)
                }
 #endif /* !oldway */
 #endif /* SUNOS4 */
-               tcpchild->flags |= TCB_ATTACHED | TCB_STARTUP;
+               tcpchild->flags |= TCB_ATTACHED | TCB_STARTUP | 
TCB_IGNORE_ONE_SIGSTOP;
                /* Child has BPT too, must be removed on first occasion */
                if (bpt) {
                        tcpchild->flags |= TCB_BPTSET;
diff -d -urpN strace.3/strace.c strace.4/strace.c
--- strace.3/strace.c   2011-09-02 16:06:04.360190184 +0200
+++ strace.4/strace.c   2011-09-02 16:06:21.864293092 +0200
@@ -491,7 +491,7 @@ startup_attach(void)
                                        cur_tcp = tcp;
                                        if (tid != tcp->pid)
                                                cur_tcp = alloctcb(tid);
-                                       cur_tcp->flags |= TCB_ATTACHED | 
TCB_STARTUP;
+                                       cur_tcp->flags |= TCB_ATTACHED | 
TCB_STARTUP | TCB_IGNORE_ONE_SIGSTOP;
                                }
                                closedir(dir);
                                if (interactive) {
@@ -512,6 +512,13 @@ startup_attach(void)
 : "Process %u attached - interrupt to quit\n",
                                                tcp->pid, ntid);
                                }
+                               if (!(tcp->flags & TCB_STARTUP)) {
+                                       /* -p PID, we failed to attach to PID 
itself
+                                        * but did attach to some of its 
sibling threads.
+                                        * Drop PID's tcp.
+                                        */
+                                       droptcb(tcp);
+                               }
                                continue;
                        } /* if (opendir worked) */
                } /* if (-f) */
@@ -521,7 +528,7 @@ startup_attach(void)
                        droptcb(tcp);
                        continue;
                }
-               tcp->flags |= TCB_STARTUP;
+               tcp->flags |= TCB_STARTUP | TCB_IGNORE_ONE_SIGSTOP;
                if (debug)
                        fprintf(stderr, "attach to pid %d (main) succeeded\n", 
tcp->pid);
 
@@ -707,7 +714,10 @@ startup_child(char **argv)
 
        if (!daemonized_tracer) {
                tcp = alloctcb(pid);
-               tcp->flags |= TCB_STARTUP;
+               if (!strace_vforked)
+                       tcp->flags |= TCB_STARTUP | TCB_IGNORE_ONE_SIGSTOP;
+               else
+                       tcp->flags |= TCB_STARTUP;
        }
        else {
                /* With -D, *we* are child here, IOW: different pid. Fetch it: 
*/
@@ -1677,11 +1687,11 @@ detach(struct tcb *tcp, int sig)
 #define PTRACE_DETACH PTRACE_SUNDETACH
 #endif
        /*
-        * On TCB_STARTUP we did PTRACE_ATTACH but still did not get the
-        * expected SIGSTOP.  We must catch exactly one as otherwise the
-        * detached process would be left stopped (process state T).
+        * We did PTRACE_ATTACH but possibly didn't see the expected SIGSTOP.
+        * We must catch exactly one as otherwise the detached process
+        * would be left stopped (process state T).
         */
-       catch_sigstop = (tcp->flags & TCB_STARTUP);
+       catch_sigstop = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
        error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig);
        if (error == 0) {
                /* On a clear day, you can see forever. */
@@ -2411,7 +2421,7 @@ trace()
                                   child so that we know how to do clearbpt
                                   in the child.  */
                                tcp = alloctcb(pid);
-                               tcp->flags |= TCB_ATTACHED | TCB_STARTUP;
+                               tcp->flags |= TCB_ATTACHED | TCB_STARTUP | 
TCB_IGNORE_ONE_SIGSTOP;
                                if (!qflag)
                                        fprintf(stderr, "Process %d attached\n",
                                                pid);
@@ -2478,28 +2488,10 @@ trace()
                        continue;
                }
 
-               if (status >> 16) {
-                       /* Ptrace event (we ignore all of them for now) */
-                       goto restart_tracee_with_sig_0;
-               }
-
-               sig = WSTOPSIG(status);
-
-               /*
-                * Interestingly, the process may stop
-                * with STOPSIG equal to some other signal
-                * than SIGSTOP if we happend to attach
-                * just before the process takes a signal.
-                * A no-MMU vforked child won't send up a signal,
-                * so skip the first (lost) execve notification.
-                */
-               if ((tcp->flags & TCB_STARTUP) &&
-                   (sig == SIGSTOP || strace_vforked)) {
-                       /*
-                        * This flag is there to keep us in sync.
-                        * Next time this process stops it should
-                        * really be entering a system call.
-                        */
+               /* Is this the very first time we see this tracee stopped? */
+               if (tcp->flags & TCB_STARTUP) {
+                       if (debug)
+                               fprintf(stderr, "pid %d has TCB_STARTUP, 
initializing it\n", tcp->pid);
                        tcp->flags &= ~TCB_STARTUP;
                        if (tcp->flags & TCB_BPTSET) {
                                /*
@@ -2525,6 +2517,25 @@ trace()
                                }
                        }
 #endif
+               }
+
+               if (((unsigned)status >> 16) != 0) {
+                       /* Ptrace event (we ignore all of them for now) */
+                       goto restart_tracee_with_sig_0;
+               }
+
+               sig = WSTOPSIG(status);
+
+               /* Is this post-attach SIGSTOP?
+                * Interestingly, the process may stop
+                * with STOPSIG equal to some other signal
+                * than SIGSTOP if we happend to attach
+                * just before the process takes a signal.
+                */
+               if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
+                       if (debug)
+                               fprintf(stderr, "ignored SIGSTOP on pid %d\n", 
tcp->pid);
+                       tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
                        goto restart_tracee_with_sig_0;
                }
 



------------------------------------------------------------------------------
Special Offer -- Download ArcSight Logger for FREE!
Finally, a world-class log management solution at an even better 
price-free! And you'll get a free "Love Thy Logs" t-shirt when you
download Logger. Secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsisghtdev2dev
_______________________________________________
Strace-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to