2007-11-06 Jan Kratochvil <jan.kratochvil@redhat.com>
* strace.c [LINUX] (droptcb): Recurse on TCP->parent if it is a TCB_EXITING zombie group leader. * test/childthread.c: New file. * test/.cvsignore, test/Makefile: Add it. Code advisory: Roland McGrath Fixes RH#354261.
This commit is contained in:
parent
f189d6d047
commit
276ceb33f2
10
strace.c
10
strace.c
@ -1297,6 +1297,16 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -4,3 +4,4 @@ skodic
|
||||
vfork
|
||||
clone
|
||||
leaderkill
|
||||
childthread
|
||||
|
@ -2,10 +2,12 @@
|
||||
# $Id$
|
||||
#
|
||||
|
||||
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
|
||||
|
||||
|
59
test/childthread.c
Normal file
59
test/childthread.c
Normal file
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user