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 10pthread_mutex_t mxC1 = PTHREAD_MUTEX_INITIALIZER; 11pthread_mutex_t mxC2 = PTHREAD_MUTEX_INITIALIZER; 12pthread_mutex_t mxC2b = PTHREAD_MUTEX_INITIALIZER; 13pthread_mutex_t mxP = PTHREAD_MUTEX_INITIALIZER; 14 15/* This one exits in the normal way, by joining back */ 16void* 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. */ 23void* 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. */ 34int 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