1 2 #include <pthread.h> 3 #include <unistd.h> 4 #include <assert.h> 5 #include <signal.h> 6 7 /* Should see 3 threads exiting in different ways, all holding one (or 8 two) locks. */ 9 10 pthread_mutex_t mxC1 = PTHREAD_MUTEX_INITIALIZER; 11 pthread_mutex_t mxC2 = PTHREAD_MUTEX_INITIALIZER; 12 pthread_mutex_t mxC2b = PTHREAD_MUTEX_INITIALIZER; 13 pthread_mutex_t mxP = PTHREAD_MUTEX_INITIALIZER; 14 15 /* This one exits in the normal way, by joining back */ 16 void* child_fn1 ( void* arg ) 17 { 18 int r= pthread_mutex_lock( &mxC1 ); assert(!r); 19 return NULL; 20 } 21 22 /* This one detaches, does its own thing. */ 23 void* child_fn2 ( void* arg ) 24 { 25 int r; 26 r= pthread_mutex_lock( &mxC2 ); assert(!r); 27 r= pthread_mutex_lock( &mxC2b ); assert(!r); 28 r= pthread_detach( pthread_self() ); assert(!r); 29 return NULL; 30 } 31 32 /* Parent creates 2 children, takes a lock, waits, segfaults. Use 33 sleeps to enforce exit ordering, for repeatable regtesting. */ 34 int main ( void ) 35 { 36 int r; 37 pthread_t child1, child2; 38 39 r= pthread_create(&child2, NULL, child_fn2, NULL); assert(!r); 40 sleep(1); 41 42 r= pthread_create(&child1, NULL, child_fn1, NULL); assert(!r); 43 r= pthread_join(child1, NULL); assert(!r); 44 sleep(1); 45 46 r= pthread_mutex_lock( &mxP ); 47 48 kill( getpid(), SIGABRT ); 49 return 0; 50 } 51