1#import <Foundation/Foundation.h> 2#import <pthread.h> 3 4long my_global; 5 6void *Thread1(void *arg) { 7 my_global = 42; 8 return NULL; 9} 10 11void *Thread2(void *arg) { 12 my_global = 144; 13 return NULL; 14} 15 16void TestDataRace1() { 17 pthread_t t1, t2; 18 pthread_create(&t1, NULL, Thread1, NULL); 19 pthread_create(&t2, NULL, Thread2, NULL); 20 21 pthread_join(t1, NULL); 22 pthread_join(t2, NULL); 23} 24 25void TestInvalidMutex() { 26 pthread_mutex_t m = {0}; 27 pthread_mutex_lock(&m); 28 29 pthread_mutex_init(&m, NULL); 30 pthread_mutex_lock(&m); 31 pthread_mutex_unlock(&m); 32 pthread_mutex_destroy(&m); 33 pthread_mutex_lock(&m); 34} 35 36void TestMutexWrongLock() { 37 pthread_mutex_t m = {0}; 38 pthread_mutex_init(&m, NULL); 39 pthread_mutex_unlock(&m); 40} 41 42long some_global; 43 44void TestDataRaceBlocks1() { 45 dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT); 46 47 for (int i = 0; i < 2; i++) { 48 dispatch_async(q, ^{ 49 some_global++; // race 1 50 51 usleep(100000); // force the blocks to be on different threads 52 }); 53 } 54 55 usleep(100000); 56 dispatch_barrier_sync(q, ^{ }); 57} 58 59void TestDataRaceBlocks2() { 60 dispatch_queue_t q = dispatch_queue_create("my.queue2", DISPATCH_QUEUE_CONCURRENT); 61 62 char *c; 63 64 c = malloc((rand() % 1000) + 10); 65 for (int i = 0; i < 2; i++) { 66 dispatch_async(q, ^{ 67 c[0] = 'x'; // race 2 68 fprintf(stderr, "tid: %p\n", pthread_self()); 69 usleep(100000); // force the blocks to be on different threads 70 }); 71 } 72 dispatch_barrier_sync(q, ^{ }); 73 74 free(c); 75} 76 77void TestUseAfterFree() { 78 char *c; 79 80 c = malloc((rand() % 1000) + 10); 81 free(c); 82 c[0] = 'x'; 83} 84 85void TestRacePipe() { 86 dispatch_queue_t q = dispatch_queue_create("my.queue3", DISPATCH_QUEUE_CONCURRENT); 87 88 int a[2]; 89 pipe(a); 90 int fd = a[0]; 91 92 for (int i = 0; i < 2; i++) { 93 dispatch_async(q, ^{ 94 write(fd, "abc", 3); 95 usleep(100000); // force the blocks to be on different threads 96 }); 97 dispatch_async(q, ^{ 98 close(fd); 99 usleep(100000); 100 }); 101 } 102 103 dispatch_barrier_sync(q, ^{ }); 104} 105 106void TestThreadLeak() { 107 pthread_t t1; 108 pthread_create(&t1, NULL, Thread1, NULL); 109} 110 111int main(int argc, const char * argv[]) { 112 TestDataRace1(); 113 114 TestInvalidMutex(); 115 116 TestMutexWrongLock(); 117 118 TestDataRaceBlocks1(); 119 120 TestDataRaceBlocks2(); 121 122 TestUseAfterFree(); 123 124 TestRacePipe(); 125 126 TestThreadLeak(); 127 128 return 0; 129} 130