1 /* Test exit of a child of a TCB_EXITING child where the toplevel process starts
2 * waiting on it. The middle one gets detached and strace must update the
3 * toplevel process'es number of attached children to 0.
4 *
5 * gcc -o test/childthread test/childthread.c -Wall -ggdb2 -pthread;./strace -f ./test/childthread
6 * It must print: write(1, "OK\n", ...
7 */
8
9 #include <pthread.h>
10 #include <assert.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <sys/wait.h>
15
start0(void * arg)16 static void *start0(void *arg)
17 {
18 pause();
19 /* NOTREACHED */
20 assert(0);
21 }
22
main(int argc,char * argv[])23 int main(int argc, char *argv[])
24 {
25 pthread_t thread0;
26 pid_t child, got_pid;
27 int status;
28 int i;
29
30 child = fork();
31
32 switch (child) {
33 case -1:
34 assert(0);
35 case 0:
36 i = pthread_create(&thread0, NULL, start0, NULL);
37 assert(i == 0);
38 /* The thread must be initialized, it becomes thread-child of this
39 process-child (child of a child of the toplevel process). */
40 sleep(1);
41 /* Here the child TCB cannot be deallocated as there still exist
42 * children (the thread child in START0). */
43 exit(42);
44 /* NOTREACHED */
45 assert(0);
46 default:
47 /* We must not be waiting in WAITPID when the child double-exits. */
48 sleep(2);
49 /* PID must be -1. */
50 got_pid = waitpid(-1, &status, 0);
51 assert(got_pid == child);
52 assert(WIFEXITED(status));
53 assert(WEXITSTATUS(status) == 42);
54 puts("OK");
55 exit(0);
56 }
57
58 /* NOTREACHED */
59 assert(0);
60 }
61