2005-08-03  Roland McGrath  <roland@redhat.com>

	* strace.c (detach): If detaching the last live thread in a group with
	a zombie leader, then detach the leader too.
	(handle_group_exit): Use detach, not droptcb, for predeceased thread.
	Mark process about to take a signal with TCB_GROUP_EXITING flag.
	Fixes RH#161919.
diff --git a/strace.c b/strace.c
index f028de3..f78458c 100644
--- a/strace.c
+++ b/strace.c
@@ -1206,6 +1206,14 @@
 	int error = 0;
 #ifdef LINUX
 	int status, resumed;
+	struct tcb *zombie = NULL;
+
+	/* If the group leader is lingering only because of this other
+	   thread now dying, then detach the leader as well.  */
+	if ((tcp->flags & TCB_CLONE_THREAD) &&
+	    tcp->parent->nclone_threads == 1 &&
+	    (tcp->parent->flags & TCB_EXITING))
+		zombie = tcp->parent;
 #endif
 
 	if (tcp->flags & TCB_BPTSET)
@@ -1364,6 +1372,12 @@
 		fprintf(stderr, "Process %u detached\n", tcp->pid);
 
 	droptcb(tcp);
+
+#ifdef LINUX
+	if (zombie != NULL)
+		error = detach(zombie) || error;
+#endif
+
 	return error;
 }
 
@@ -1941,9 +1955,11 @@
 			fprintf(stderr,
 				"PANIC: handle_group_exit: %d leader %d\n",
 				tcp->pid, leader ? leader->pid : -1);
-		droptcb(tcp);	/* Already died.  */
+		detach(tcp);	/* Already died.  */
 	}
 	else {
+		/* Mark that we are taking the process down.  */
+		tcp->flags |= TCB_EXITING | TCB_GROUP_EXITING;
 		if (tcp->flags & TCB_ATTACHED) {
 		  	if (leader != NULL && leader != tcp) {
 				if (leader->flags & TCB_ATTACHED) {