/* 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 #include #include #include #include #include static void *start0(void *arg) { pause(); /* NOTREACHED */ assert(0); } int main(int argc, char *argv[]) { pthread_t thread0; pid_t child, got_pid; int status; int i; 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); }