90 lines · c
1// Test that mach_vm_[de]allocate resets shadow memory status.2//3// RUN: %clang_tsan %s -o %t4// RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer'5 6// <mach/mach_vm.h> is not provided by the simulator SDK.7// UNSUPPORTED: iossim8 9#include <mach/mach.h>10#include <mach/mach_vm.h>11#include <pthread.h>12#include <assert.h>13#include <stdio.h>14 15#include "../test.h"16 17const mach_vm_size_t alloc_size = sizeof(int);18static int *global_ptr;19 20static int *alloc() {21 mach_vm_address_t addr;22 kern_return_t kr =23 mach_vm_allocate(mach_task_self(), &addr, alloc_size, VM_FLAGS_ANYWHERE);24 assert(kr == KERN_SUCCESS);25 return (int *)addr;26}27 28static void alloc_fixed(int *ptr) {29 mach_vm_address_t addr = (mach_vm_address_t)ptr;30 // Re-allocation via VM_FLAGS_FIXED sporadically fails.31 kern_return_t kr =32 mach_vm_allocate(mach_task_self(), &addr, alloc_size, VM_FLAGS_FIXED);33 if (kr != KERN_SUCCESS)34 global_ptr = NULL;35}36 37static void dealloc(int *ptr) {38 kern_return_t kr =39 mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)ptr, alloc_size);40 assert(kr == KERN_SUCCESS);41}42 43static void *Thread(void *arg) {44 *global_ptr = 7; // Assignment 145 46 // We want to test that TSan does not report a race between the two47 // assignments to *global_ptr when the underlying memory is re-allocated48 // between assignments. The calls to the API itself are racy though, so ignore49 // them.50 AnnotateIgnoreWritesBegin(__FILE__, __LINE__);51 dealloc(global_ptr);52 alloc_fixed(global_ptr);53 AnnotateIgnoreWritesEnd(__FILE__, __LINE__);54 55 barrier_wait(&barrier);56 return NULL;57}58 59static bool try_realloc_on_same_address() {60 barrier_init(&barrier, 2);61 global_ptr = alloc();62 pthread_t t;63 pthread_create(&t, NULL, Thread, NULL);64 65 barrier_wait(&barrier);66 if (global_ptr)67 *global_ptr = 8; // Assignment 268 69 pthread_join(t, NULL);70 dealloc(global_ptr);71 72 return global_ptr != NULL;73}74 75int main(int argc, const char *argv[]) {76 bool success;77 for (int i = 0; i < 10; i++) {78 success = try_realloc_on_same_address();79 if (success) break;80 }81 82 if (!success)83 fprintf(stderr, "Unable to set up testing condition; silently pass test\n");84 85 printf("Done.\n");86 return 0;87}88 89// CHECK: Done.90