Remove tcp->parent and TCB_CLONE_THREAD.

tcp->parent is used for only two things:
(1) to send signal on detach via tgkill (need to know tgid).
Solution: use tkill, it needs only tid.
(2) to optimize out ptrace options setting for new tracees.
Not a big deal if we drop this optimization: "set options" op is fast,
doing it just one extra time once per each tracee is hardly measurable.

TCB_CLONE_THREAD is a misnomer. It used only to flag sibling we attached to
in startup_attach. This is used to prevent infinite recursive rescanning
of /proc/PID/task.
Despite the name, there is no guarantee it is set only on non-leader:
if one would run "strace -f -p THREAD_ID" and THREAD_ID is *not*
a thread leader, strace will happily attach to it and all siblings
and will think that THREAD_ID is the leader! Which is a bug, but
since we no longer detach when we think tracee is going to die,
this bug no longer matters, because we do not use the knowledge
about thread group leaders for anything. (We used it to delay
leader's exit).

IOW: after this patch strace has no need to know about threads, parents
and children, and so on. Therefore it does not track that information.
It treats all tracees as independent entities. Overall,
this simplifies code a lot.

* defs.h: Add TCB_ATTACH_DONE flag, remove TCB_CLONE_THREAD flag
and struct tcb::parent field.
* process.c (internal_fork): Don't set tcpchild->parent.
* strace.c (startup_attach): Use TCB_ATTACH_DONE flag instead of
TCB_CLONE_THREAD to avoid attach attempts on already-attached threads.
Unlike TCB_CLONE_THREAD, TCB_ATTACH_DONE bit is used only temporarily,
and only in this function. We clear it on every tcb before we return.
(detach): Use tkill instead of tgkill.
(trace): Set ptrace options on new tracees unconditionally,
not only when tcp->parent == NULL.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
diff --git a/strace.c b/strace.c
index b2ebb54..1d79cc4 100644
--- a/strace.c
+++ b/strace.c
@@ -49,16 +49,14 @@
 
 #ifdef LINUX
 # include <asm/unistd.h>
-# if defined __NR_tgkill
-#  define my_tgkill(pid, tid, sig) syscall(__NR_tgkill, (pid), (tid), (sig))
-# elif defined __NR_tkill
-#  define my_tgkill(pid, tid, sig) syscall(__NR_tkill, (tid), (sig))
+# if defined __NR_tkill
+#  define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig))
 # else
    /* kill() may choose arbitrarily the target task of the process group
       while we later wait on a that specific TID.  PID process waits become
       TID task specific waits for a process under ptrace(2).  */
 #  warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!"
-#  define my_tgkill(pid, tid, sig) kill((tid), (sig))
+#  define my_tkill(tid, sig) kill((tid), (sig))
 # endif
 #endif
 
@@ -436,10 +434,11 @@
 
 	for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
 		tcp = tcbtab[tcbi];
+
 		if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED))
 			continue;
 #ifdef LINUX
-		if (tcp->flags & TCB_CLONE_THREAD)
+		if (tcp->flags & TCB_ATTACH_DONE)
 			continue;
 #endif
 		/* Reinitialize the output since it may have changed. */
@@ -479,16 +478,15 @@
 					else {
 						if (debug)
 							fprintf(stderr, "attach to pid %d succeeded\n", tid);
-						if (tid != tcbtab[tcbi]->pid) {
-							tcp = alloctcb(tid);
-							tcp->flags |= TCB_ATTACHED|TCB_CLONE_THREAD;
-							tcp->parent = tcbtab[tcbi];
+						if (tid != tcp->pid) {
+							struct tcb *new_tcp = alloctcb(tid);
+							new_tcp->flags |= TCB_ATTACHED|TCB_ATTACH_DONE;
 						}
 					}
 					if (interactive) {
 						sigprocmask(SIG_SETMASK, &empty_set, NULL);
 						if (interrupted)
-							return;
+							goto ret;
 						sigprocmask(SIG_BLOCK, &blocked_set, NULL);
 					}
 				}
@@ -503,12 +501,12 @@
 					fprintf(stderr, ntid > 1
 ? "Process %u attached with %u threads - interrupt to quit\n"
 : "Process %u attached - interrupt to quit\n",
-						tcbtab[tcbi]->pid, ntid);
+						tcp->pid, ntid);
 				}
 				continue;
 			} /* if (opendir worked) */
 		} /* if (-f) */
-# endif
+# endif /* LINUX */
 		if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) {
 			perror("attach: ptrace(PTRACE_ATTACH, ...)");
 			droptcb(tcp);
@@ -537,6 +535,15 @@
 				tcp->pid);
 	} /* for each tcbtab[] */
 
+ ret:
+#ifdef LINUX
+	/* TCB_ATTACH_DONE flag is used only in this function */
+	for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
+		tcp = tcbtab[tcbi];
+		tcp->flags &= ~TCB_ATTACH_DONE;
+	}
+#endif
+
 	if (interactive)
 		sigprocmask(SIG_SETMASK, &empty_set, NULL);
 }
@@ -1621,15 +1628,11 @@
 		/* Shouldn't happen. */
 		perror("detach: ptrace(PTRACE_DETACH, ...)");
 	}
-	else if (my_tgkill((tcp->flags & TCB_CLONE_THREAD ? tcp->parent->pid
-							  : tcp->pid),
-			   tcp->pid, 0) < 0) {
+	else if (my_tkill(tcp->pid, 0) < 0) {
 		if (errno != ESRCH)
 			perror("detach: checking sanity");
 	}
-	else if (!catch_sigstop && my_tgkill((tcp->flags & TCB_CLONE_THREAD
-					      ? tcp->parent->pid : tcp->pid),
-					     tcp->pid, SIGSTOP) < 0) {
+	else if (!catch_sigstop && my_tkill(tcp->pid, SIGSTOP) < 0) {
 		if (errno != ESRCH)
 			perror("detach: stopping child");
 	}
@@ -2443,16 +2446,13 @@
 				}
 			}
 #ifdef LINUX
-			/* If options were not set for this tracee yet */
-			if (tcp->parent == NULL) {
-				if (ptrace_setoptions) {
-					if (debug)
-						fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
-					if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
-						if (errno != ESRCH) {
-							/* Should never happen, really */
-							perror_msg_and_die("PTRACE_SETOPTIONS");
-						}
+			if (ptrace_setoptions) {
+				if (debug)
+					fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
+				if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
+					if (errno != ESRCH) {
+						/* Should never happen, really */
+						perror_msg_and_die("PTRACE_SETOPTIONS");
 					}
 				}
 			}