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 9int *x; 10 11void *AllocThread(void *arg) { 12 x = new int; 13 *x = 42; 14 return NULL; 15} 16 17void *FreeThread(void *arg) { 18 delete x; 19 return NULL; 20} 21 22void *AccessThread(void *arg) { 23 *x = 43; // BOOM 24 return NULL; 25} 26 27typedef void* (*callback_type)(void* arg); 28 29void *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 36void RunThread(callback_type function) { 37 pthread_t runner; 38 pthread_create(&runner, NULL, RunnerThread, (void*)function); 39 pthread_join(runner, NULL); 40} 41 42int 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