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//
5// REQUIRES: x86_64-target-arch
6
7#include <assert.h>
8#include <pthread.h>
9#include <sanitizer/dfsan_interface.h>
10#include <stdlib.h>
11
12static unsigned char GlobalBuf[4096];
13static int ShutDownThread;
14static int StartFlush;
15
16// Access GlobalBuf continuously, causing its shadow to be touched as well.
17// When main() calls dfsan_flush(), no segfault should be triggered.
18static void *accessGlobalInBackground(void *Arg) {
19 __atomic_store_n(&StartFlush, 1, __ATOMIC_RELEASE);
20
21 while (!__atomic_load_n(&ShutDownThread, __ATOMIC_ACQUIRE))
22 for (unsigned I = 0; I < sizeof(GlobalBuf); ++I)
23 ++GlobalBuf[I];
24
25 return NULL;
26}
27
28int main() {
29 pthread_t Thread;
30 pthread_create(&Thread, NULL, accessGlobalInBackground, NULL);
31 while (!__atomic_load_n(&StartFlush, __ATOMIC_ACQUIRE))
32 ; // Spin
33
34 dfsan_flush();
35
36 __atomic_store_n(&ShutDownThread, 1, __ATOMIC_RELEASE);
37 pthread_join(Thread, NULL);
38 return 0;
39}
40