Skip to content

Commit

Permalink
[tsan] Ensure mmap respects ignore_interceptors_accesses
Browse files Browse the repository at this point in the history
The ignore_interceptors_accesses setting did not have an effect on mmap, so
let's change that. It helps in cases user code is accessing the memory
written to by mmap when the synchronization is ensured by the code that
does not get rebuilt.

(This effects Swift interoperability since it's runtime is mapping memory
which gets accessed by the code emitted into the Swift application by the
compiler.)

Differential Revision: http://reviews.llvm.org/D20294

llvm-svn: 269855
  • Loading branch information
AnnaZaks committed May 17, 2016
1 parent 1054570 commit 7d47c99
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 2 deletions.
12 changes: 10 additions & 2 deletions compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,11 @@ TSAN_INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags,
if (res != MAP_FAILED) {
if (fd > 0)
FdAccess(thr, pc, fd);
MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);

if (thr->ignore_reads_and_writes == 0)
MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);
else
MemoryResetRange(thr, pc, (uptr)res, sz);
}
return res;
}
Expand All @@ -726,7 +730,11 @@ TSAN_INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags,
if (res != MAP_FAILED) {
if (fd > 0)
FdAccess(thr, pc, fd);
MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);

if (thr->ignore_reads_and_writes == 0)
MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);
else
MemoryResetRange(thr, pc, (uptr)res, sz);
}
return res;
}
Expand Down
61 changes: 61 additions & 0 deletions compiler-rt/test/tsan/ignored-interceptors-mmap.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// RUN: %clangxx_tsan -O0 %s -o %t
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NORMAL
// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORE

#include <errno.h>
#include <sys/mman.h>

#include "test.h"

extern "C" {
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);
}

void *global_p;

int mmap_and_ignore_reads_and_writes() {
const size_t kSize = sysconf(_SC_PAGESIZE);
void *p = mmap(0, kSize, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANON, -1, 0);
if (p == MAP_FAILED)
return printf("mmap failed with %d\n", errno);
munmap(p, kSize);

void *new_p = mmap(p, kSize, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANON, -1, 0);
if (p == MAP_FAILED || p != new_p)
return printf("second mmap failed with %d\n", errno);

AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
global_p = p;
AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
barrier_wait(&barrier);
return 0;
}

void *Thread(void *a) {
barrier_wait(&barrier);

((int*)global_p)[1] = 10;
printf("Read the zero value from mmapped memory %d\n", ((int*)global_p)[1]);
return 0;
}

int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
if (mmap_and_ignore_reads_and_writes())
return 1;
pthread_join(t, 0);
printf("OK\n");
return 0;
}

// CHECK-NORMAL: WARNING: ThreadSanitizer: data race
// CHECK-NORMAL: OK
// CHECK-IGNORE_NOT: WARNING: ThreadSanitizer: data race
// CHECK-IGNORE: OK

0 comments on commit 7d47c99

Please sign in to comment.