summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2013-09-20 05:37:36 +0000
committerDmitry Vyukov <dvyukov@google.com>2013-09-20 05:37:36 +0000
commitff90a95c26198e9e794e186365a62511439e0ca0 (patch)
tree7b7099e8fd91ddf5f8d070c876009ce42295c96b
parent9880219fc988d9fd60c8aa21c0f6f0e0d7370dd6 (diff)
tsan: allow to ignore memory accesses in malloc and free
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@191072 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/tsan/lit_tests/ignore_free.cc35
-rw-r--r--lib/tsan/lit_tests/ignore_malloc.cc38
-rw-r--r--lib/tsan/rtl/tsan_mman.cc14
3 files changed, 83 insertions, 4 deletions
diff --git a/lib/tsan/lit_tests/ignore_free.cc b/lib/tsan/lit_tests/ignore_free.cc
new file mode 100644
index 000000000..60369cc1b
--- /dev/null
+++ b/lib/tsan/lit_tests/ignore_free.cc
@@ -0,0 +1,35 @@
+// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.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 *Thread(void *p) {
+ *(int*)p = 42;
+ return 0;
+}
+
+int main() {
+ int *p = new int(0);
+ pthread_t t;
+ pthread_create(&t, 0, Thread, p);
+ sleep(1);
+ AnnotateIgnoreReadsBegin(__FILE__, __LINE__);
+ AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
+ free(p);
+ AnnotateIgnoreReadsEnd(__FILE__, __LINE__);
+ AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
+ pthread_join(t, 0);
+ fprintf(stderr, "OK\n");
+ return 0;
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer: data race
+// CHECK: OK
diff --git a/lib/tsan/lit_tests/ignore_malloc.cc b/lib/tsan/lit_tests/ignore_malloc.cc
new file mode 100644
index 000000000..63bd4241b
--- /dev/null
+++ b/lib/tsan/lit_tests/ignore_malloc.cc
@@ -0,0 +1,38 @@
+// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.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);
+}
+
+int *g;
+
+void *Thread(void *a) {
+ int *p = 0;
+ while ((p = __atomic_load_n(&g, __ATOMIC_RELAXED)) == 0)
+ usleep(100);
+ *p = 42;
+ return 0;
+}
+
+int main() {
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
+ int *p = new int(0);
+ AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
+ __atomic_store_n(&g, p, __ATOMIC_RELAXED);
+ pthread_join(t, 0);
+ delete p;
+ fprintf(stderr, "OK\n");
+ return 0;
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer: data race
+// CHECK: OK
diff --git a/lib/tsan/rtl/tsan_mman.cc b/lib/tsan/rtl/tsan_mman.cc
index 957479039..8547f714b 100644
--- a/lib/tsan/rtl/tsan_mman.cc
+++ b/lib/tsan/rtl/tsan_mman.cc
@@ -110,8 +110,12 @@ void *user_alloc(ThreadState *thr, uptr pc, uptr sz, uptr align) {
return 0;
MBlock *b = new(allocator()->GetMetaData(p)) MBlock;
b->Init(sz, thr->tid, CurrentStackId(thr, pc));
- if (CTX() && CTX()->initialized)
- MemoryRangeImitateWrite(thr, pc, (uptr)p, sz);
+ if (CTX() && CTX()->initialized) {
+ if (thr->ignore_reads_and_writes == 0)
+ MemoryRangeImitateWrite(thr, pc, (uptr)p, sz);
+ else
+ MemoryResetRange(thr, pc, (uptr)p, sz);
+ }
DPrintf("#%d: alloc(%zu) = %p\n", thr->tid, sz, p);
SignalUnsafeCall(thr, pc);
return p;
@@ -134,8 +138,10 @@ void user_free(ThreadState *thr, uptr pc, void *p) {
}
b->ListReset();
}
- if (CTX() && CTX()->initialized && thr->in_rtl == 1)
- MemoryRangeFreed(thr, pc, (uptr)p, b->Size());
+ if (CTX() && CTX()->initialized && thr->in_rtl == 1) {
+ if (thr->ignore_reads_and_writes == 0)
+ MemoryRangeFreed(thr, pc, (uptr)p, b->Size());
+ }
allocator()->Deallocate(&thr->alloc_cache, p);
SignalUnsafeCall(thr, pc);
}