1 // RUN: %clangxx_asan -O0 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 2 // RUN: %clangxx_asan -O1 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 3 // RUN: %clangxx_asan -O2 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 4 // RUN: %clangxx_asan -O3 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 5 // REQUIRES: stable-runtime 6 7 #include <pthread.h> 8 9 int *x; 10 11 void *AllocThread(void *arg) { 12 x = new int; 13 *x = 42; 14 return NULL; 15 } 16 17 void *FreeThread(void *arg) { 18 delete x; 19 return NULL; 20 } 21 22 void *AccessThread(void *arg) { 23 *x = 43; // BOOM 24 return NULL; 25 } 26 27 typedef void* (*callback_type)(void* arg); 28 29 void *RunnerThread(void *function) { 30 pthread_t thread; 31 pthread_create(&thread, NULL, (callback_type)function, NULL); 32 pthread_join(thread, NULL); 33 return NULL; 34 } 35 36 void RunThread(callback_type function) { 37 pthread_t runner; 38 pthread_create(&runner, NULL, RunnerThread, (void*)function); 39 pthread_join(runner, NULL); 40 } 41 42 int main(int argc, char *argv[]) { 43 RunThread(AllocThread); 44 RunThread(FreeThread); 45 RunThread(AccessThread); 46 return (x != 0); 47 } 48 49 // CHECK: AddressSanitizer: heap-use-after-free 50 // CHECK: WRITE of size 4 at 0x{{.*}} thread T[[ACCESS_THREAD:[0-9]+]] 51 // CHECK: freed by thread T[[FREE_THREAD:[0-9]+]] here: 52 // CHECK: previously allocated by thread T[[ALLOC_THREAD:[0-9]+]] here: 53 // CHECK: Thread T[[ACCESS_THREAD]] created by T[[ACCESS_RUNNER:[0-9]+]] here: 54 // CHECK: Thread T[[ACCESS_RUNNER]] created by T0 here: 55 // CHECK: Thread T[[FREE_THREAD]] created by T[[FREE_RUNNER:[0-9]+]] here: 56 // CHECK: Thread T[[FREE_RUNNER]] created by T0 here: 57 // CHECK: Thread T[[ALLOC_THREAD]] created by T[[ALLOC_RUNNER:[0-9]+]] here: 58 // CHECK: Thread T[[ALLOC_RUNNER]] created by T0 here: 59