brintos

brintos / llvm-project-archived public Read only

0
0
Text · 1.9 KiB · 1fbc77e Raw
64 lines · c
1// RUN: %clang_tsan %s -o %t && %run %t | FileCheck %s2 3// In these systems, the behavior of ReleaseMemoryPagesToOS is madvise(beg, end, MADV_FREE),4// which tags the relevant pages as 'FREE' and does not release them immediately.5// Therefore, we cannot assume that __tsan_read1 will not race with the shadow cleared.6// UNSUPPORTED: darwin,target={{.*(freebsd|netbsd|solaris|haiku).*}}7 8#include "test.h"9#include <assert.h>10#include <pthread.h>11#include <stdint.h>12#include <stdio.h>13#include <sys/mman.h>14#include <unistd.h>15 16void __tsan_read1(void *addr);17 18struct thread_params {19  char *buf;20  unsigned int size;21};22 23static void *thread_func(void *arg) {24  struct thread_params *p = (struct thread_params *)arg;25  // Access 126  p->buf[0] = 0x42;27  p->buf[p->size - 1] = 0x42;28  barrier_wait(&barrier);29  return 0;30}31 32int main() {33  const unsigned int kPageSize = sysconf(_SC_PAGESIZE);34  // The relevant shadow memory size should be exactly multiple of kPageSize,35  // even if Size = kPageSize - 1.36  const unsigned int Size = kPageSize - 1;37 38  barrier_init(&barrier, 2);39  char *buf = (char *)mmap(NULL, Size, PROT_READ | PROT_WRITE,40                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);41  assert(buf != MAP_FAILED);42  assert(((uintptr_t)buf % kPageSize) == 0);43 44  pthread_t t;45  struct thread_params p = {buf, Size};46  pthread_create(&t, 0, thread_func, &p);47 48  barrier_wait(&barrier);49  // Should clear all the shadow memory related to the mmaped memory.50  munmap(buf, Size);51 52  // If the shadow memory is cleared completely, the following reads should not53  // cause races and behave the same. However, previously, __tsan_read1(&buf[0])54  // would not report a race, while __tsan_read1(&buf[Size - 1]) did.55  // CHECK-NOT: WARNING: ThreadSanitizer: data race56  __tsan_read1(&buf[0]);        // Access 257  __tsan_read1(&buf[Size - 1]); // Access 258  pthread_join(t, 0);59 60  puts("DONE");61 62  return 0;63}64