1b411202f9ff33a587558e2e836626bc7eb9db183sewardj/* This program attempts to verify that all functions that are 2b411202f9ff33a587558e2e836626bc7eb9db183sewardj supposed to be wrapped by tc_intercepts.c really are wrapped. The 3b411202f9ff33a587558e2e836626bc7eb9db183sewardj main way it does this is to cause failures in those functions, so 4b411202f9ff33a587558e2e836626bc7eb9db183sewardj as to obtain various error messages which imply that the wrapper 5b411202f9ff33a587558e2e836626bc7eb9db183sewardj really did engage. 6b411202f9ff33a587558e2e836626bc7eb9db183sewardj 7b411202f9ff33a587558e2e836626bc7eb9db183sewardj Any regressions shown up by this program are potentially serious 8b411202f9ff33a587558e2e836626bc7eb9db183sewardj and should be investigated carefully. */ 9b411202f9ff33a587558e2e836626bc7eb9db183sewardj 10b411202f9ff33a587558e2e836626bc7eb9db183sewardj/* Needed for older glibcs (2.3 and older, at least) who don't 11b411202f9ff33a587558e2e836626bc7eb9db183sewardj otherwise "know" about some more exotic pthread stuff, in this case 12b411202f9ff33a587558e2e836626bc7eb9db183sewardj PTHREAD_MUTEX_ERRORCHECK. */ 13b411202f9ff33a587558e2e836626bc7eb9db183sewardj#define _GNU_SOURCE 1 14b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <stdio.h> 15b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <string.h> 16b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <assert.h> 17b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <unistd.h> 1802b13a1023bf6d80d04095e71004d26498758b51tom#include "safe-pthread.h" 190c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw#include "safe-semaphore.h" 20b411202f9ff33a587558e2e836626bc7eb9db183sewardj 216e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#if !defined(__APPLE__) 222ee33955b80812a8f31ec06a0430103b50aeca8csewardj 238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(__sun__) 248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Fake __GLIBC_PREREQ on Solaris. Pretend glibc >= 2.4. */ 258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# define __GLIBC_PREREQ 268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#else 27b411202f9ff33a587558e2e836626bc7eb9db183sewardj#if !defined(__GLIBC_PREREQ) 28b411202f9ff33a587558e2e836626bc7eb9db183sewardj# error "This program needs __GLIBC_PREREQ (in /usr/include/features.h)" 29b411202f9ff33a587558e2e836626bc7eb9db183sewardj#endif 308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif /* __sun__ */ 31b411202f9ff33a587558e2e836626bc7eb9db183sewardj 32a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef union { 33a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes pthread_spinlock_t spinlock; 34a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes pthread_rwlock_t rwlock; 35a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} spin_rw_lock; 36a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 37b411202f9ff33a587558e2e836626bc7eb9db183sewardjshort unprotected = 0; 38b411202f9ff33a587558e2e836626bc7eb9db183sewardj 39b411202f9ff33a587558e2e836626bc7eb9db183sewardjvoid* lazy_child ( void* v ) { 40b411202f9ff33a587558e2e836626bc7eb9db183sewardj assert(0); /* does not run */ 41b411202f9ff33a587558e2e836626bc7eb9db183sewardj} 42b411202f9ff33a587558e2e836626bc7eb9db183sewardj 43b411202f9ff33a587558e2e836626bc7eb9db183sewardjvoid* racy_child ( void* v ) { 44b411202f9ff33a587558e2e836626bc7eb9db183sewardj unprotected = 1234; 45b411202f9ff33a587558e2e836626bc7eb9db183sewardj return NULL; 46b411202f9ff33a587558e2e836626bc7eb9db183sewardj} 47b411202f9ff33a587558e2e836626bc7eb9db183sewardj 48b411202f9ff33a587558e2e836626bc7eb9db183sewardjint main ( void ) 49b411202f9ff33a587558e2e836626bc7eb9db183sewardj{ 50b411202f9ff33a587558e2e836626bc7eb9db183sewardj int r; 51b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* pthread_t thr; */ 52b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* pthread_attr_t thra; */ 53b411202f9ff33a587558e2e836626bc7eb9db183sewardj pthread_mutexattr_t mxa, mxa2; 54b411202f9ff33a587558e2e836626bc7eb9db183sewardj pthread_mutex_t mx, mx2, mx3, mx4; 55b411202f9ff33a587558e2e836626bc7eb9db183sewardj pthread_cond_t cv; 56b411202f9ff33a587558e2e836626bc7eb9db183sewardj struct timespec abstime; 57b411202f9ff33a587558e2e836626bc7eb9db183sewardj pthread_rwlock_t rwl; 58b411202f9ff33a587558e2e836626bc7eb9db183sewardj pthread_rwlock_t rwl2; 59b411202f9ff33a587558e2e836626bc7eb9db183sewardj pthread_rwlock_t rwl3; 60b411202f9ff33a587558e2e836626bc7eb9db183sewardj sem_t s1; 61b411202f9ff33a587558e2e836626bc7eb9db183sewardj 62b411202f9ff33a587558e2e836626bc7eb9db183sewardj# if __GLIBC_PREREQ(2,4) 63b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, 64b411202f9ff33a587558e2e836626bc7eb9db183sewardj "\n\n------ This is output for >= glibc 2.4 ------\n"); 65b411202f9ff33a587558e2e836626bc7eb9db183sewardj# else 66b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, 67b411202f9ff33a587558e2e836626bc7eb9db183sewardj "\n\n------ This is output for < glibc 2.4 ------\n"); 68b411202f9ff33a587558e2e836626bc7eb9db183sewardj# endif 69b411202f9ff33a587558e2e836626bc7eb9db183sewardj 70b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* --------- pthread_create/join --------- */ 71b411202f9ff33a587558e2e836626bc7eb9db183sewardj 72b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, 73b411202f9ff33a587558e2e836626bc7eb9db183sewardj "\n---------------- pthread_create/join ----------------\n\n"); 74b411202f9ff33a587558e2e836626bc7eb9db183sewardj 75b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_create fail */ 76b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* It's amazingly difficult to make pthread_create fail 77b411202f9ff33a587558e2e836626bc7eb9db183sewardj without first soaking up all the machine's resources. 78b411202f9ff33a587558e2e836626bc7eb9db183sewardj Instead, in order to demonstrate that it's really wrapped, 79b411202f9ff33a587558e2e836626bc7eb9db183sewardj create a child thread, generate a race error, and join with it 80b411202f9ff33a587558e2e836626bc7eb9db183sewardj again. */ 81b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* This just segfaults: 82b411202f9ff33a587558e2e836626bc7eb9db183sewardj memset( &thra, 0xFF, sizeof(thra) ); 83b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_create( &thr, NULL, lazy_child, NULL ); assert(r); 84b411202f9ff33a587558e2e836626bc7eb9db183sewardj */ 85b411202f9ff33a587558e2e836626bc7eb9db183sewardj { pthread_t child; 86b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_create( &child, NULL, racy_child, NULL ); assert(!r); 87b411202f9ff33a587558e2e836626bc7eb9db183sewardj sleep(1); /* just to ensure parent thread reports race, not child */ 88b411202f9ff33a587558e2e836626bc7eb9db183sewardj unprotected = 5678; 89b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_join( child, NULL ); assert(!r); 90b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 91b411202f9ff33a587558e2e836626bc7eb9db183sewardj 92b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_join fail */ 93b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_join( pthread_self(), NULL ); assert(r); 94b411202f9ff33a587558e2e836626bc7eb9db183sewardj 95b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* --------- pthread_mutex_lock et al --------- */ 96b411202f9ff33a587558e2e836626bc7eb9db183sewardj 97b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, 98b411202f9ff33a587558e2e836626bc7eb9db183sewardj "\n---------------- pthread_mutex_lock et al ----------------\n\n"); 99b411202f9ff33a587558e2e836626bc7eb9db183sewardj 100b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_mutex_init fail */ 1018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(__sun__) 1028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj pthread_mutexattr_init( &mxa ); 1038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj memset( mxa.__pthread_mutexattrp, 0xFF, 5 * sizeof(int) ); 1048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#else 105b411202f9ff33a587558e2e836626bc7eb9db183sewardj memset( &mxa, 0xFF, sizeof(mxa) ); 1068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif 107b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_mutex_init( &mx, &mxa ); 108b411202f9ff33a587558e2e836626bc7eb9db183sewardj# if __GLIBC_PREREQ(2,4) 109b411202f9ff33a587558e2e836626bc7eb9db183sewardj assert(r); /* glibc >= 2.4: the call should fail */ 110b411202f9ff33a587558e2e836626bc7eb9db183sewardj# else 111b411202f9ff33a587558e2e836626bc7eb9db183sewardj assert(!r); /* glibc < 2.4: oh well, glibc didn't bounce this */ 112b411202f9ff33a587558e2e836626bc7eb9db183sewardj# endif 113b411202f9ff33a587558e2e836626bc7eb9db183sewardj 114b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_mutex_destroy fail */ 115b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_mutex_init( &mx2, NULL ); assert(!r); 116b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_mutex_lock( &mx2 ); assert(!r); 117d94082ef226012b4ed34155262deeeede2fe3e54bart r= pthread_mutex_destroy( &mx2 ); 118b411202f9ff33a587558e2e836626bc7eb9db183sewardj 119b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_mutex_lock fail (skipped on < glibc 2.4 because it 120b411202f9ff33a587558e2e836626bc7eb9db183sewardj doesn't fail, hence hangs the test) */ 121b411202f9ff33a587558e2e836626bc7eb9db183sewardj# if __GLIBC_PREREQ(2,4) 122b411202f9ff33a587558e2e836626bc7eb9db183sewardj memset( &mx3, 0xFF, sizeof(mx3) ); 123b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_mutex_lock( &mx3 ); assert(r); 124b411202f9ff33a587558e2e836626bc7eb9db183sewardj# else 125b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "\nmake pthread_mutex_lock fail: " 126b411202f9ff33a587558e2e836626bc7eb9db183sewardj "skipped on glibc < 2.4\n\n"); 127b411202f9ff33a587558e2e836626bc7eb9db183sewardj# endif 128b411202f9ff33a587558e2e836626bc7eb9db183sewardj 129b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_mutex_trylock fail */ 130b411202f9ff33a587558e2e836626bc7eb9db183sewardj memset( &mx3, 0xFF, sizeof(mx3) ); 131b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_mutex_trylock( &mx3 ); assert(r); 132b411202f9ff33a587558e2e836626bc7eb9db183sewardj 133b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_mutex_timedlock fail */ 134b411202f9ff33a587558e2e836626bc7eb9db183sewardj memset( &abstime, 0, sizeof(abstime) ); 135b411202f9ff33a587558e2e836626bc7eb9db183sewardj memset( &mx3, 0xFF, sizeof(mx3) ); 136b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_mutex_timedlock( &mx3, &abstime ); assert(r); 137b411202f9ff33a587558e2e836626bc7eb9db183sewardj 138b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_mutex_unlock fail */ 139b411202f9ff33a587558e2e836626bc7eb9db183sewardj memset( &mx3, 0xFF, sizeof(mx3) ); 140b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_mutex_unlock( &mx3 ); 141b411202f9ff33a587558e2e836626bc7eb9db183sewardj# if __GLIBC_PREREQ(2,4) 142b411202f9ff33a587558e2e836626bc7eb9db183sewardj assert(r); 143b411202f9ff33a587558e2e836626bc7eb9db183sewardj# else 144b411202f9ff33a587558e2e836626bc7eb9db183sewardj assert(!r); 145b411202f9ff33a587558e2e836626bc7eb9db183sewardj# endif 146b411202f9ff33a587558e2e836626bc7eb9db183sewardj 147b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* --------- pthread_cond_wait et al --------- */ 148b411202f9ff33a587558e2e836626bc7eb9db183sewardj 149b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, 150b411202f9ff33a587558e2e836626bc7eb9db183sewardj "\n---------------- pthread_cond_wait et al ----------------\n\n"); 151b411202f9ff33a587558e2e836626bc7eb9db183sewardj 152b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_cond_wait fail. This is difficult. Our cunning 153b411202f9ff33a587558e2e836626bc7eb9db183sewardj plan (tm) is to show up at pthread_cond_wait bearing a 154b411202f9ff33a587558e2e836626bc7eb9db183sewardj not-locked mutex of the ERRORCHECK flavour and hope (as is 155b411202f9ff33a587558e2e836626bc7eb9db183sewardj indeed the case with glibc-2.5) that pthread_cond_wait notices 156b411202f9ff33a587558e2e836626bc7eb9db183sewardj it is not locked, and bounces our request. */ 157b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_mutexattr_init( &mxa2 ); assert(!r); 158b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_mutexattr_settype( &mxa2, PTHREAD_MUTEX_ERRORCHECK ); 159b411202f9ff33a587558e2e836626bc7eb9db183sewardj assert(!r); 160b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_mutex_init( &mx4, &mxa2 ); assert(!r); 161b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_cond_init( &cv, NULL ); assert(!r); 162b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_cond_wait( &cv, &mx4 ); assert(r); 163b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_mutexattr_destroy( &mxa2 ); assert(!r); 164b411202f9ff33a587558e2e836626bc7eb9db183sewardj 165b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_cond_signal fail. FIXME: can't figure out how 166b411202f9ff33a587558e2e836626bc7eb9db183sewardj to */ 167b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_cond_signal( &cv ); assert(!r); 168b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "\nFIXME: can't figure out how to " 169b411202f9ff33a587558e2e836626bc7eb9db183sewardj "verify wrap of pthread_cond_signal\n\n"); 170b411202f9ff33a587558e2e836626bc7eb9db183sewardj 171b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_cond_broadcast fail. FIXME: can't figure out how 172b411202f9ff33a587558e2e836626bc7eb9db183sewardj to */ 173b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_cond_broadcast( &cv ); assert(!r); 174b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "\nFIXME: can't figure out how to " 175b411202f9ff33a587558e2e836626bc7eb9db183sewardj "verify wrap of pthread_broadcast_signal\n\n"); 176b411202f9ff33a587558e2e836626bc7eb9db183sewardj 177b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* make pthread_cond_timedwait fail. */ 178b411202f9ff33a587558e2e836626bc7eb9db183sewardj memset( &abstime, 0, sizeof(abstime) ); 179b411202f9ff33a587558e2e836626bc7eb9db183sewardj abstime.tv_nsec = 1000000000 + 1; 180b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_cond_timedwait( &cv, &mx4, &abstime ); assert(r); 181b411202f9ff33a587558e2e836626bc7eb9db183sewardj 182b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* --------- pthread_rwlock_* --------- */ 183b411202f9ff33a587558e2e836626bc7eb9db183sewardj 184b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, 185b411202f9ff33a587558e2e836626bc7eb9db183sewardj "\n---------------- pthread_rwlock_* ----------------\n\n"); 186b411202f9ff33a587558e2e836626bc7eb9db183sewardj 187b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* pthread_rwlock_init, pthread_rwlock_unlock */ 188b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* pthread_rwlock_init: can't make glibc's implementation fail. 189b411202f9ff33a587558e2e836626bc7eb9db183sewardj However, can demonstrate interceptedness by initialising but not 190b411202f9ff33a587558e2e836626bc7eb9db183sewardj locking a lock and then unlocking it. Then the unlock call 191b411202f9ff33a587558e2e836626bc7eb9db183sewardj should say "first seen at .. the init call." So this tests 192b411202f9ff33a587558e2e836626bc7eb9db183sewardj wrappedness of both calls. */ 193b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_init( &rwl, NULL ); assert(!r); 194b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_unlock( &rwl ); 195b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* assert(r); *//* glibc doesn't complain. It really ought to. Oh well. */ 196b411202f9ff33a587558e2e836626bc7eb9db183sewardj 197b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* We can infer the presence of wrapping for pthread_rwlock_rdlock, 198b411202f9ff33a587558e2e836626bc7eb9db183sewardj pthread_rwlock_wrlock and pthread_rwlock_unlock by making 199b411202f9ff33a587558e2e836626bc7eb9db183sewardj Thrcheck count the lockedness state, and warning when we unlock 200b411202f9ff33a587558e2e836626bc7eb9db183sewardj a not-locked lock. Thusly: */ 201b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_init( &rwl2, NULL ); assert(!r); 202b411202f9ff33a587558e2e836626bc7eb9db183sewardj 203b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* w-lock it */ 204b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "(1) no error on next line\n"); 205b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_wrlock( &rwl2 ); assert(!r); 206b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* unlock it */ 207b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "(2) no error on next line\n"); 208b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_unlock( &rwl2 ); assert(!r); 209b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* unlock it again, get an error */ 210b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "(3) ERROR on next line\n"); 2118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj r= pthread_rwlock_unlock( &rwl2 ); 2128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(__sun__) 2138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj assert(r); 2148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#else 2158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj assert(!r); 2168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif 217b411202f9ff33a587558e2e836626bc7eb9db183sewardj 218b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* same game with r-locks */ 219b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_init( &rwl2, NULL ); assert(!r); 220b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* r-lock it twice */ 221b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "(4) no error on next line\n"); 222b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_rdlock( &rwl2 ); assert(!r); 223b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "(5) no error on next line\n"); 224b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_rdlock( &rwl2 ); assert(!r); 225b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* unlock it twice */ 226b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "(6) no error on next line\n"); 227b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_unlock( &rwl2 ); assert(!r); 228b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "(7) no error on next line\n"); 229b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_unlock( &rwl2 ); assert(!r); 230b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* unlock it again, get an error */ 231b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "(8) ERROR on next line\n"); 2328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj r= pthread_rwlock_unlock( &rwl2 ); 2338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(__sun__) 2348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj assert(r); 2358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#else 2368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj assert(!r); 2378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif 238b411202f9ff33a587558e2e836626bc7eb9db183sewardj 239b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* Lock rwl3 so the locked-lock-at-dealloc check can complain about 240b411202f9ff33a587558e2e836626bc7eb9db183sewardj it. */ 241b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_init( &rwl3, NULL ); assert(!r); 242b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= pthread_rwlock_rdlock( &rwl3 ); assert(!r); 243b411202f9ff33a587558e2e836626bc7eb9db183sewardj 244a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* --------- pthread_spin_* --------- */ 245a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 246a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes fprintf(stderr, 247a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "\n---------------- pthread_spin_* ----------------\n\n"); 248a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 249a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* The following sequence verifies correct wrapping of pthread_spin_init() 250a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes and pthread_spin_destroy(). */ 251a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes spin_rw_lock srwl1; 252a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes pthread_spin_init(&srwl1.spinlock, PTHREAD_PROCESS_PRIVATE); 253a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes pthread_spin_destroy(&srwl1.spinlock); 254a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 255a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes pthread_rwlock_init(&srwl1.rwlock, NULL); 256a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes pthread_rwlock_destroy(&srwl1.rwlock); 257a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 258b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* ------------- sem_* ------------- */ 259b411202f9ff33a587558e2e836626bc7eb9db183sewardj 260b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* This is pretty lame, and duplicates tc18_semabuse.c. */ 261b411202f9ff33a587558e2e836626bc7eb9db183sewardj 262b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, 263b411202f9ff33a587558e2e836626bc7eb9db183sewardj "\n---------------- sem_* ----------------\n\n"); 264b411202f9ff33a587558e2e836626bc7eb9db183sewardj 265b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* verifies wrap of sem_init */ 266b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* Do sem_init with huge initial count - fails */ 267b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= sem_init(&s1, 0, ~0); assert(r); 268b411202f9ff33a587558e2e836626bc7eb9db183sewardj 269b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* initialise properly */ 270b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= sem_init(&s1, 0, 0); 271b411202f9ff33a587558e2e836626bc7eb9db183sewardj 272b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* in glibc, sem_destroy is a no-op; making it fail is 273b411202f9ff33a587558e2e836626bc7eb9db183sewardj impossible. */ 274b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "\nFIXME: can't figure out how to verify wrap of " 275b411202f9ff33a587558e2e836626bc7eb9db183sewardj "sem_destroy\n\n"); 276b411202f9ff33a587558e2e836626bc7eb9db183sewardj 277b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* verifies wrap of sem_wait */ 278b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* Do 'wait' on a bogus semaphore. This should fail, but on glibc 279b411202f9ff33a587558e2e836626bc7eb9db183sewardj it succeeds. */ 280b411202f9ff33a587558e2e836626bc7eb9db183sewardj memset(&s1, 0x55, sizeof(s1)); 281b411202f9ff33a587558e2e836626bc7eb9db183sewardj r= sem_wait(&s1); /* assert(r != 0); */ 282b411202f9ff33a587558e2e836626bc7eb9db183sewardj 283612c87b192fc6e5466d16ac6bb2448f1224e6fc9bart /* this only fails with glibc 2.7 or later. */ 284612c87b192fc6e5466d16ac6bb2448f1224e6fc9bart r= sem_post(&s1); 285b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, "\nFIXME: can't figure out how to verify wrap of " 286b411202f9ff33a587558e2e836626bc7eb9db183sewardj "sem_post\n\n"); 287b411202f9ff33a587558e2e836626bc7eb9db183sewardj 288b411202f9ff33a587558e2e836626bc7eb9db183sewardj sem_destroy(&s1); 289b411202f9ff33a587558e2e836626bc7eb9db183sewardj 290b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* ------------- dealloc of mem holding locks ------------- */ 291b411202f9ff33a587558e2e836626bc7eb9db183sewardj 292b411202f9ff33a587558e2e836626bc7eb9db183sewardj fprintf(stderr, 293b411202f9ff33a587558e2e836626bc7eb9db183sewardj "\n------------ dealloc of mem holding locks ------------\n\n"); 294b411202f9ff33a587558e2e836626bc7eb9db183sewardj 295b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* At this point it should complain about deallocation 296b411202f9ff33a587558e2e836626bc7eb9db183sewardj of memory containing locked locks: 297b411202f9ff33a587558e2e836626bc7eb9db183sewardj rwl3 298b411202f9ff33a587558e2e836626bc7eb9db183sewardj */ 299b411202f9ff33a587558e2e836626bc7eb9db183sewardj 300b411202f9ff33a587558e2e836626bc7eb9db183sewardj return 0; 301b411202f9ff33a587558e2e836626bc7eb9db183sewardj} 3022ee33955b80812a8f31ec06a0430103b50aeca8csewardj 3036e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#else /* defined(__APPLE__) */ 3042ee33955b80812a8f31ec06a0430103b50aeca8csewardjint main ( void ) 3052ee33955b80812a8f31ec06a0430103b50aeca8csewardj{ 3066e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj fprintf(stderr, "This program does not work on Mac OS X.\n"); 3072ee33955b80812a8f31ec06a0430103b50aeca8csewardj return 0; 3082ee33955b80812a8f31ec06a0430103b50aeca8csewardj} 3092ee33955b80812a8f31ec06a0430103b50aeca8csewardj#endif 310