]> granicus.if.org Git - strace/commitdiff
2004-10-19 Roland McGrath <roland@redhat.com>
authorRoland McGrath <roland@redhat.com>
Wed, 20 Oct 2004 01:00:27 +0000 (01:00 +0000)
committerRoland McGrath <roland@redhat.com>
Wed, 20 Oct 2004 01:00:27 +0000 (01:00 +0000)
* strace.c (trace): Use handle_group_exit for non-TCB_ATTACHED child
taking signal when it has nclone_threads > 0.
* strace.c (handle_group_exit): Don't detach leader that wasn't
TCB_ATTACHED.
* strace.c (handle_group_exit, trace): Mark leader with
TCB_GROUP_EXITING and don't be surprised at child deaths when their
leader has it set.
Fixes RH#132150.

strace.c

index 02441fcc992c9ab543b0da3f9a78ae87add93890..ce7701e306ac227ca5491f29464bf95dd5170404 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -1926,9 +1926,12 @@ handle_group_exit(struct tcb *tcp, int sig)
                              ? tcp->parent
                              : tcp->nclone_detached > 0
                              ? tcp : NULL);
+       fprintf(stderr,"handle_group_exit (%d [%d], %d)\n", tcp->pid,
+               leader? leader->pid:-1, sig);
 
        if (sig < 0) {
-               if (leader != NULL && leader != tcp)
+               if (leader != NULL && leader != tcp &&
+                   !(leader->flags & TCB_GROUP_EXITING))
                        fprintf(stderr,
                                "PANIC: handle_group_exit: %d leader %d\n",
                                tcp->pid, leader ? leader->pid : -1);
@@ -1936,7 +1939,8 @@ handle_group_exit(struct tcb *tcp, int sig)
        }
        else {
                if (tcp->flags & TCB_ATTACHED) {
-                       if (leader != NULL && leader != tcp) {
+                       if (leader != NULL && leader != tcp &&
+                               (leader->flags & TCB_ATTACHED)) {
                                /* We need to detach the leader so that the
                                   process death will be reported to its real
                                   parent.  But we kill it first to prevent
@@ -1961,6 +1965,8 @@ handle_group_exit(struct tcb *tcp, int sig)
                        return -1;
                }
                else {
+                       if (leader != NULL)
+                               leader->flags |= TCB_GROUP_EXITING;
                        if (leader != NULL && leader != tcp)
                                droptcb(tcp);
                        /* The leader will report to us as parent now,
@@ -2140,7 +2146,12 @@ Process %d attached (waiting for parent)\n",
                if (WIFEXITED(status)) {
                        if (debug)
                                fprintf(stderr, "pid %u exited\n", pid);
-                       if (tcp->flags & TCB_ATTACHED)
+                       if ((tcp->flags & TCB_ATTACHED)
+#ifdef TCB_GROUP_EXITING
+                           && !(tcp->parent && (tcp->parent->flags &
+                                                TCB_GROUP_EXITING))
+#endif
+                               )
                                fprintf(stderr,
                                        "PANIC: attached pid %u exited\n",
                                        pid);
@@ -2242,7 +2253,8 @@ Process %d attached (waiting for parent)\n",
                                        strsignal(WSTOPSIG(status)), pc, addr);
                                printtrailer(tcp);
                        }
-                       if ((tcp->flags & TCB_ATTACHED) &&
+                       if (((tcp->flags & TCB_ATTACHED) ||
+                            tcp->nclone_threads > 0) &&
                                !sigishandled(tcp, WSTOPSIG(status))) {
 #ifdef TCB_GROUP_EXITING
                                handle_group_exit(tcp, WSTOPSIG(status));