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 16 static void *start0(void *arg) 17 { 18 pause(); 19 /* NOTREACHED */ 20 assert(0); 21 } 22 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