| |
| /* Check that an error is reported for various kinds of bogus |
| pthread_mutex_unlock calls. */ |
| |
| #include <pthread.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| void* child_fn ( void* arg ) |
| { |
| pthread_mutex_unlock( (pthread_mutex_t*)arg ); /* ERROR */ |
| return NULL; |
| } |
| |
| void nearly_main ( void ) |
| { |
| pthread_t child; |
| pthread_mutex_t mx1, mx2; |
| int bogus[100], i; |
| /* fill bogus with values which will cause glibc's pth_mx_unlock to fail */ |
| for (i = 0; i < 100; i++) bogus[i] = 0xFFFFFFFF; |
| /* Unlocking a lock that is already unlocked */ |
| pthread_mutex_init( &mx1, NULL ); |
| pthread_mutex_lock( &mx1 ); |
| pthread_mutex_unlock( &mx1 ); |
| |
| pthread_mutex_unlock( &mx1 ); /* ERROR */ |
| |
| /* Unlocking a lock that is held by a different thread */ |
| |
| pthread_mutex_init( &mx2, NULL ); |
| pthread_mutex_lock( &mx2 ); |
| // start child and get it to unlock this lock |
| |
| pthread_create( &child, NULL, child_fn, (void*)&mx2 ); |
| /* child runs and attempts to unlock our lock. Error |
| is reported in child_fn. */ |
| pthread_join(child, NULL ); |
| |
| /* Unlocking a totally bogus lock. */ |
| pthread_mutex_unlock( (pthread_mutex_t*) &bogus[50] ); /* ERROR */ |
| |
| /* Now we get a freeing-locked-lock error, since the stack |
| frame is removed whilst mx2 is still locked. */ |
| } |
| |
| int main ( void ) |
| { |
| nearly_main(); fprintf(stderr, "---------------------\n" ); |
| nearly_main(); |
| return 0; |
| } |