]> granicus.if.org Git - strace/commitdiff
2005-08-03 Roland McGrath <roland@redhat.com>
authorRoland McGrath <roland@redhat.com>
Wed, 3 Aug 2005 11:23:46 +0000 (11:23 +0000)
committerRoland McGrath <roland@redhat.com>
Wed, 3 Aug 2005 11:23:46 +0000 (11:23 +0000)
* 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.

strace.c

index f028de39288f6094541fd4d0794a4d36f9a6768d..f78458c3183e00c47c18c4a8465e133f82cca757 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -1206,6 +1206,14 @@ int sig;
        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 @@ int sig;
                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 @@ handle_group_exit(struct tcb *tcp, int sig)
                        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) {