1 // Stress test recovery mode with many threads. 2 // 3 // RUN: %clangxx_asan -fsanitize-recover=address -pthread %s -o %t 4 // 5 // RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=false %run %t 1 10 >1.txt 2>&1 6 // RUN: FileCheck %s < 1.txt 7 // RUN: [ $(grep -c 'ERROR: AddressSanitizer: use-after-poison' 1.txt) -eq 10 ] 8 // RUN: FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt 9 // 10 // Collisions are unlikely but still possible so we need the ||. 11 // RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=false %run %t 10 20 >10.txt 2>&1 || true 12 // This one is racy although _very_ unlikely to fail: 13 // RUN: FileCheck %s < 10.txt 14 // RUN: FileCheck --check-prefix=CHECK-COLLISION %s < 1.txt || FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt 15 // 16 // Collisions are unlikely but still possible so we need the ||. 17 // RUN: %env_asan_opts=halt_on_error=false %run %t 10 20 >10.txt 2>&1 || true 18 // This one is racy although _very_ unlikely to fail: 19 // RUN: FileCheck %s < 10.txt 20 // RUN: FileCheck --check-prefix=CHECK-COLLISION %s < 1.txt || FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <pthread.h> 25 #include <time.h> 26 27 #include <sanitizer/asan_interface.h> 28 29 size_t nthreads = 10; 30 size_t niter = 10; 31 32 void random_delay(unsigned *seed) { 33 *seed = 1664525 * *seed + 1013904223; 34 struct timespec delay = { 0, (*seed % 1000) * 1000 }; 35 nanosleep(&delay, 0); 36 } 37 38 void *run(void *arg) { 39 unsigned seed = (unsigned)(size_t)arg; 40 41 volatile char tmp[2]; 42 __asan_poison_memory_region(&tmp, sizeof(tmp)); 43 44 for (size_t i = 0; i < niter; ++i) { 45 random_delay(&seed); 46 // Expect error collisions here 47 // CHECK: ERROR: AddressSanitizer: use-after-poison 48 volatile int idx = 0; 49 tmp[idx] = 0; 50 } 51 52 return 0; 53 } 54 55 int main(int argc, char **argv) { 56 if (argc != 3) { 57 fprintf(stderr, "Syntax: %s nthreads niter\n", argv[0]); 58 exit(1); 59 } 60 61 nthreads = (size_t)strtoul(argv[1], 0, 0); 62 niter = (size_t)strtoul(argv[2], 0, 0); 63 64 pthread_t *tids = new pthread_t[nthreads]; 65 66 for (size_t i = 0; i < nthreads; ++i) { 67 if (0 != pthread_create(&tids[i], 0, run, (void *)i)) { 68 fprintf(stderr, "Failed to create thread\n"); 69 exit(1); 70 } 71 } 72 73 for (size_t i = 0; i < nthreads; ++i) { 74 if (0 != pthread_join(tids[i], 0)) { 75 fprintf(stderr, "Failed to join thread\n"); 76 exit(1); 77 } 78 } 79 80 // CHECK-COLLISION: AddressSanitizer: nested bug in the same thread, aborting 81 // CHECK-NO-COLLISION: All threads terminated 82 printf("All threads terminated\n"); 83 84 delete [] tids; 85 86 return 0; 87 } 88