1 // Tests that doing dfsan_flush() while another thread is executing doesn't 2 // segfault. 3 // RUN: %clang_dfsan %s -o %t && %run %t 4 #include <assert.h> 5 #include <pthread.h> 6 #include <sanitizer/dfsan_interface.h> 7 #include <stdlib.h> 8 9 static unsigned char GlobalBuf[4096]; 10 static int ShutDownThread; 11 static int StartFlush; 12 13 // Access GlobalBuf continuously, causing its shadow to be touched as well. 14 // When main() calls dfsan_flush(), no segfault should be triggered. 15 static void *accessGlobalInBackground(void *Arg) { 16 __atomic_store_n(&StartFlush, 1, __ATOMIC_RELEASE); 17 18 while (!__atomic_load_n(&ShutDownThread, __ATOMIC_ACQUIRE)) 19 for (unsigned I = 0; I < sizeof(GlobalBuf); ++I) 20 ++GlobalBuf[I]; 21 22 return NULL; 23 } 24 25 int main() { 26 pthread_t Thread; 27 pthread_create(&Thread, NULL, accessGlobalInBackground, NULL); 28 while (!__atomic_load_n(&StartFlush, __ATOMIC_ACQUIRE)) 29 ; // Spin 30 31 dfsan_flush(); 32 33 __atomic_store_n(&ShutDownThread, 1, __ATOMIC_RELEASE); 34 pthread_join(Thread, NULL); 35 return 0; 36 } 37