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) {