1// { dg-do run { target pthread } } 2// { dg-options "-lasan -lpthread" } 3// { dg-shouldfail "asan" } 4 5#include <pthread.h> 6 7int *x; 8 9void *AllocThread(void *arg) { 10 x = new int; 11 *x = 42; 12 return NULL; 13} 14 15void *FreeThread(void *arg) { 16 delete x; 17 return NULL; 18} 19 20void *AccessThread(void *arg) { 21 *x = 43; // BOOM 22 return NULL; 23} 24 25typedef void* (*callback_type)(void* arg); 26 27void *RunnerThread(void *function) { 28 pthread_t thread; 29 pthread_create(&thread, NULL, (callback_type)function, NULL); 30 pthread_join(thread, NULL); 31 return NULL; 32} 33 34void RunThread(callback_type function) { 35 pthread_t runner; 36 pthread_create(&runner, NULL, RunnerThread, (void*)function); 37 pthread_join(runner, NULL); 38} 39 40int main(int argc, char *argv[]) { 41 RunThread(AllocThread); 42 RunThread(FreeThread); 43 RunThread(AccessThread); 44 return (x != 0); 45} 46 47// { dg-output "ERROR: AddressSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } 48// { dg-output "\[^\n\r]*WRITE of size 4 at 0x\[0-9a-f\]+ thread T(\[0-9\]+).*(\n|\r\n|\r)" } 49// { dg-output "\[^\n\r]*freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } 50// { dg-output "\[^\n\r]*previously allocated by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } 51// { dg-output "Thread T\\2 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } 52// { dg-output "Thread T\\8 created by T0 here:.*(\n|\r\n|\r)" } 53// { dg-output "Thread T\\4 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } 54// { dg-output "Thread T\\11 created by T0 here:.*(\n|\r\n|\r)" } 55// { dg-output "Thread T\\6 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } 56// { dg-output "Thread T\\14 created by T0 here:" } 57