Skip to content

Commit 41a8ddb

Browse files
committed
[tsan] Ensure mmap respects ignore_interceptors_accesses
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 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@269855 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent fcc6038 commit 41a8ddb

File tree

2 files changed

+71
-2
lines changed

2 files changed

+71
-2
lines changed

lib/tsan/rtl/tsan_interceptors.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,11 @@ TSAN_INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags,
711711
if (res != MAP_FAILED) {
712712
if (fd > 0)
713713
FdAccess(thr, pc, fd);
714-
MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);
714+
715+
if (thr->ignore_reads_and_writes == 0)
716+
MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);
717+
else
718+
MemoryResetRange(thr, pc, (uptr)res, sz);
715719
}
716720
return res;
717721
}
@@ -726,7 +730,11 @@ TSAN_INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags,
726730
if (res != MAP_FAILED) {
727731
if (fd > 0)
728732
FdAccess(thr, pc, fd);
729-
MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);
733+
734+
if (thr->ignore_reads_and_writes == 0)
735+
MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);
736+
else
737+
MemoryResetRange(thr, pc, (uptr)res, sz);
730738
}
731739
return res;
732740
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// RUN: %clangxx_tsan -O0 %s -o %t
2+
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NORMAL
3+
// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORE
4+
5+
#include <errno.h>
6+
#include <sys/mman.h>
7+
8+
#include "test.h"
9+
10+
extern "C" {
11+
void AnnotateIgnoreReadsBegin(const char *f, int l);
12+
void AnnotateIgnoreReadsEnd(const char *f, int l);
13+
void AnnotateIgnoreWritesBegin(const char *f, int l);
14+
void AnnotateIgnoreWritesEnd(const char *f, int l);
15+
}
16+
17+
void *global_p;
18+
19+
int mmap_and_ignore_reads_and_writes() {
20+
const size_t kSize = sysconf(_SC_PAGESIZE);
21+
void *p = mmap(0, kSize, PROT_READ|PROT_WRITE,
22+
MAP_PRIVATE|MAP_ANON, -1, 0);
23+
if (p == MAP_FAILED)
24+
return printf("mmap failed with %d\n", errno);
25+
munmap(p, kSize);
26+
27+
void *new_p = mmap(p, kSize, PROT_READ|PROT_WRITE,
28+
MAP_PRIVATE|MAP_ANON, -1, 0);
29+
if (p == MAP_FAILED || p != new_p)
30+
return printf("second mmap failed with %d\n", errno);
31+
32+
AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
33+
global_p = p;
34+
AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
35+
barrier_wait(&barrier);
36+
return 0;
37+
}
38+
39+
void *Thread(void *a) {
40+
barrier_wait(&barrier);
41+
42+
((int*)global_p)[1] = 10;
43+
printf("Read the zero value from mmapped memory %d\n", ((int*)global_p)[1]);
44+
return 0;
45+
}
46+
47+
int main() {
48+
barrier_init(&barrier, 2);
49+
pthread_t t;
50+
pthread_create(&t, 0, Thread, 0);
51+
if (mmap_and_ignore_reads_and_writes())
52+
return 1;
53+
pthread_join(t, 0);
54+
printf("OK\n");
55+
return 0;
56+
}
57+
58+
// CHECK-NORMAL: WARNING: ThreadSanitizer: data race
59+
// CHECK-NORMAL: OK
60+
// CHECK-IGNORE_NOT: WARNING: ThreadSanitizer: data race
61+
// CHECK-IGNORE: OK

0 commit comments

Comments
 (0)