diff options
author | Julian Lettner <jlettner@apple.com> | 2019-09-09 18:57:32 +0000 |
---|---|---|
committer | Julian Lettner <jlettner@apple.com> | 2019-09-09 18:57:32 +0000 |
commit | a5142c0c415d0c6565a82a7c109d6f9677971bda (patch) | |
tree | b080bbd5813daaade2a87491903c0b0fadbe91e4 /test/tsan/Darwin | |
parent | 111bf961e73352018a6500dd4658f5dd000bc7d8 (diff) | |
download | compiler-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.c | 73 |
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. |