[patch] Lockup on wait on exited child with exited child
Jan Kratochvil
jan.kratochvil at redhat.com
Tue Nov 6 21:04:10 UTC 2007
Hi Roland,
you were right, updated.
Thanks,
Jan
On Sun, 04 Nov 2007 00:55:14 +0100, Roland McGrath wrote:
> I think that drops it early (while still waiting for a report from the
> parent) in case of a normal parent that just happens to be almost finished
> exiting. Unless I'm missing something, this extra droptcb should only be
> required in the case of a zombie group leader that has already reported
> and been short-circuited at the top of droptcb. So I think it want the
> same test used at the top of detach.
>
>
> Thanks,
> Roland
-------------- next part --------------
2007-11-06 Jan Kratochvil <jan.kratochvil at redhat.com>
* strace.c [LINUX] (droptcb): DROPTCB even PARENT if PARENT is
TCB_EXITING zombie group leader.
* test/childthread.c: New file.
* test/.cvsignore, test/Makefile: Add it.
Code advisory: Roland McGrath
Fixes RH#354261.
--- strace.c 3 Nov 2007 23:34:11 -0000 1.84
+++ strace.c 6 Nov 2007 20:59:48 -0000
@@ -1297,6 +1297,17 @@ struct tcb *tcp;
if (!(tcp->flags & TCB_CLONE_DETACHED))
#endif
tcp->parent->nzombies++;
+#ifdef LINUX
+ /* Update `tcp->parent->parent->nchildren' and the other fields
+ like NCLONE_DETACHED, only for zombie group leader that has
+ already reported and been short-circuited at the top of this
+ function. The same condition as at the top of DETACH. */
+ if ((tcp->flags & TCB_CLONE_THREAD) &&
+ tcp->parent->nclone_threads == 0 &&
+ (tcp->parent->flags & TCB_EXITING)) {
+ droptcb(tcp->parent);
+ }
+#endif
tcp->parent = NULL;
}
--- test/.cvsignore 5 Jul 2007 18:43:18 -0000 1.3
+++ test/.cvsignore 6 Nov 2007 20:59:49 -0000
@@ -4,3 +4,4 @@ skodic
vfork
clone
leaderkill
+childthread
--- test/Makefile 5 Jul 2007 18:43:18 -0000 1.5
+++ test/Makefile 6 Nov 2007 20:59:49 -0000
@@ -2,10 +2,12 @@
# $Id: Makefile,v 1.5 2007/07/05 18:43:18 roland Exp $
#
-all: vfork fork sig skodic clone leaderkill
+all: vfork fork sig skodic clone leaderkill childthread
leaderkill: LDFLAGS += -pthread
+childthread: LDFLAGS += -pthread
+
clean distclean:
rm -f clone vfork fork sig leaderkill *.o core
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/childthread.c 6 Nov 2007 20:59:49 -0000
@@ -0,0 +1,59 @@
+/* Test exit of a child of a TCB_EXITING child where the toplevel process starts
+ * waiting on it. The middle one gets detached and strace must update the
+ * toplevel process'es number of attached children to 0.
+ *
+ * gcc -o test/childthread test/childthread.c -Wall -ggdb2 -pthread;./strace -f ./test/childthread
+ * It must print: write(1, "OK\n", ...
+ */
+
+#include <pthread.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/wait.h>
+
+static void *start0 (void *arg)
+{
+ pause ();
+ /* NOTREACHED */
+ assert (0);
+}
+
+int main (void)
+{
+ pthread_t thread0;
+ int i;
+ pid_t child, got_pid;
+ int status;
+
+ child = fork ();
+ switch (child)
+ {
+ case -1:
+ assert (0);
+ case 0:
+ i = pthread_create (&thread0, NULL, start0, NULL);
+ assert (i == 0);
+ /* The thread must be initialized, it becomes thread-child of this
+ process-child (child of a child of the toplevel process). */
+ sleep (1);
+ /* Here the child TCB cannot be deallocated as there still exist
+ * children (the thread child in START0). */
+ exit (42);
+ /* NOTREACHED */
+ assert (0);
+ default:
+ /* We must not be waiting in WAITPID when the child double-exits. */
+ sleep (2);
+ /* PID must be -1. */
+ got_pid = waitpid (-1, &status, 0);
+ assert (got_pid == child);
+ assert (WIFEXITED (status));
+ assert (WEXITSTATUS (status) == 42);
+ puts ("OK");
+ exit (0);
+ }
+ /* NOTREACHED */
+ assert (0);
+}
More information about the Strace-devel
mailing list