summaryrefslogtreecommitdiff
path: root/test/tsan/Darwin
diff options
context:
space:
mode:
authorJulian Lettner <jlettner@apple.com>2019-09-09 18:57:32 +0000
committerJulian Lettner <jlettner@apple.com>2019-09-09 18:57:32 +0000
commita5142c0c415d0c6565a82a7c109d6f9677971bda (patch)
treeb080bbd5813daaade2a87491903c0b0fadbe91e4 /test/tsan/Darwin
parent111bf961e73352018a6500dd4658f5dd000bc7d8 (diff)
downloadcompiler-rt-a5142c0c415d0c6565a82a7c109d6f9677971bda.tar.gz
[TSan] Add interceptors for mach_vm_[de]allocate
I verified that the test is red without the interceptors. rdar://40334350 Reviewed By: kubamracek, vitalybuka Differential Revision: https://reviews.llvm.org/D66616 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@371439 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/tsan/Darwin')
-rw-r--r--test/tsan/Darwin/mach_vm_allocate.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/test/tsan/Darwin/mach_vm_allocate.c b/test/tsan/Darwin/mach_vm_allocate.c
new file mode 100644
index 000000000..df3cdec71
--- /dev/null
+++ b/test/tsan/Darwin/mach_vm_allocate.c
@@ -0,0 +1,73 @@
+// Test that mach_vm_[de]allocate resets shadow memory status.
+//
+// RUN: %clang_tsan %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer'
+
+#include <mach/mach.h>
+#include <mach/mach_vm.h>
+#include <pthread.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "../test.h"
+
+void AnnotateIgnoreReadsBegin(const char *f, int l);
+void AnnotateIgnoreReadsEnd(const char *f, int l);
+void AnnotateIgnoreWritesBegin(const char *f, int l);
+void AnnotateIgnoreWritesEnd(const char *f, int l);
+
+static int *global_ptr;
+const mach_vm_size_t alloc_size = sizeof(int);
+
+static int *alloc() {
+ mach_vm_address_t addr;
+ kern_return_t res =
+ mach_vm_allocate(mach_task_self(), &addr, alloc_size, VM_FLAGS_ANYWHERE);
+ assert(res == KERN_SUCCESS);
+ return (int *)addr;
+}
+
+static void alloc_fixed(int *ptr) {
+ mach_vm_address_t addr = (mach_vm_address_t)ptr;
+ kern_return_t res =
+ mach_vm_allocate(mach_task_self(), &addr, alloc_size, VM_FLAGS_FIXED);
+ assert(res == KERN_SUCCESS);
+}
+
+static void dealloc(int *ptr) {
+ kern_return_t res =
+ mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)ptr, alloc_size);
+ assert(res == KERN_SUCCESS);
+}
+
+static void *Thread(void *arg) {
+ *global_ptr = 7; // Assignment 1
+
+ // We want to test that TSan does not report a race between the two
+ // assignments to global_ptr when memory is re-allocated here. The calls to
+ // the API itself are racy though, so ignore them.
+ AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
+ dealloc(global_ptr);
+ alloc_fixed(global_ptr);
+ AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
+
+ barrier_wait(&barrier);
+ return NULL;;
+}
+
+int main(int argc, const char *argv[]) {
+ barrier_init(&barrier, 2);
+ global_ptr = alloc();
+ pthread_t t;
+ pthread_create(&t, NULL, Thread, NULL);
+
+ barrier_wait(&barrier);
+ *global_ptr = 8; // Assignment 2
+
+ pthread_join(t, NULL);
+ dealloc(global_ptr);
+ printf("Done.\n");
+ return 0;
+}
+
+// CHECK: Done.