Roland McGrath | 276ceb3 | 2007-11-13 08:12:12 +0000 | [diff] [blame] | 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. |
Denys Vlasenko | b1efe53 | 2008-12-23 16:14:42 +0000 | [diff] [blame] | 4 | * |
Roland McGrath | 276ceb3 | 2007-11-13 08:12:12 +0000 | [diff] [blame] | 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 | |
Denys Vlasenko | 8ed5727 | 2009-02-25 14:24:02 +0000 | [diff] [blame^] | 16 | static void *start0(void *arg) |
Roland McGrath | 276ceb3 | 2007-11-13 08:12:12 +0000 | [diff] [blame] | 17 | { |
Denys Vlasenko | 8ed5727 | 2009-02-25 14:24:02 +0000 | [diff] [blame^] | 18 | pause(); |
| 19 | /* NOTREACHED */ |
| 20 | assert(0); |
Roland McGrath | 276ceb3 | 2007-11-13 08:12:12 +0000 | [diff] [blame] | 21 | } |
| 22 | |
Denys Vlasenko | 8ed5727 | 2009-02-25 14:24:02 +0000 | [diff] [blame^] | 23 | int main(int argc, char *argv[]) |
Roland McGrath | 276ceb3 | 2007-11-13 08:12:12 +0000 | [diff] [blame] | 24 | { |
Denys Vlasenko | 8ed5727 | 2009-02-25 14:24:02 +0000 | [diff] [blame^] | 25 | pthread_t thread0; |
| 26 | pid_t child, got_pid; |
| 27 | int status; |
| 28 | int i; |
Roland McGrath | 276ceb3 | 2007-11-13 08:12:12 +0000 | [diff] [blame] | 29 | |
Denys Vlasenko | 8ed5727 | 2009-02-25 14:24:02 +0000 | [diff] [blame^] | 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); |
Roland McGrath | 276ceb3 | 2007-11-13 08:12:12 +0000 | [diff] [blame] | 60 | } |