[patch] Lockup on wait on exited child with exited child

Jan Kratochvil jan.kratochvil at redhat.com
Sat Nov 3 17:35:56 UTC 2007


Hi,

attached the fix+testcase where under STRACE the execution hangs.
While I am not 100% sure of the patch it appears right to me.


Regards,
Jan

Problem reported at:
	https://bugzilla.redhat.com/show_bug.cgi?id=354261
-------------- next part --------------
2007-11-03  Jan Kratochvil  <jan.kratochvil at redhat.com>

	* strace.c (droptcb): DROPTCB even PARENT if PARENT is TCB_EXITING.
	* test/childthread.c: New file.
	* test/.cvsignore, test/Makefile: Add it.
	Fixes RH#354261.

--- strace.c	8 Oct 2007 21:04:41 -0000	1.83
+++ strace.c	3 Nov 2007 17:27:39 -0000
@@ -1285,6 +1285,11 @@ struct tcb *tcp;
 		if (!(tcp->flags & TCB_CLONE_DETACHED))
 #endif
 			tcp->parent->nzombies++;
+		if (tcp->parent->flags & TCB_EXITING) {
+			/* Update `tcp->parent->parent->nchildren' and the
+			   other fields like NCLONE_DETACHED.  */
+			droptcb(tcp->parent);
+		}
 		tcp->parent = NULL;
 	}
 
--- test/.cvsignore	5 Jul 2007 18:43:18 -0000	1.3
+++ test/.cvsignore	3 Nov 2007 17:27:39 -0000
@@ -4,3 +4,4 @@ skodic
 vfork
 clone
 leaderkill
+childthread
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ test/childthread.c	3 Nov 2007 17:27:39 -0000
@@ -0,0 +1,60 @@
+/* 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:
+	abort ();
+      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);
+	break;
+      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);
+}
--- test/Makefile	5 Jul 2007 18:43:18 -0000	1.5
+++ test/Makefile	3 Nov 2007 17:32:18 -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
 


More information about the Strace-devel mailing list