summaryrefslogtreecommitdiff
path: root/lib/tsan
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tsan')
-rw-r--r--lib/tsan/rtl/tsan_external.cc31
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc4
-rw-r--r--lib/tsan/rtl/tsan_interceptors.h2
-rw-r--r--lib/tsan/rtl/tsan_report.cc4
-rw-r--r--lib/tsan/rtl/tsan_rtl.h1
-rw-r--r--lib/tsan/rtl/tsan_rtl_report.cc2
6 files changed, 26 insertions, 18 deletions
diff --git a/lib/tsan/rtl/tsan_external.cc b/lib/tsan/rtl/tsan_external.cc
index dc8ec62322ce2..88468e4066513 100644
--- a/lib/tsan/rtl/tsan_external.cc
+++ b/lib/tsan/rtl/tsan_external.cc
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
#include "tsan_rtl.h"
+#include "tsan_interceptors.h"
namespace __tsan {
@@ -29,6 +30,20 @@ const char *GetObjectTypeFromTag(uptr tag) {
return registered_tags[tag];
}
+typedef void(*AccessFunc)(ThreadState *, uptr, uptr, int);
+void ExternalAccess(void *addr, void *caller_pc, void *tag, AccessFunc access) {
+ CHECK_LT(tag, atomic_load(&used_tags, memory_order_relaxed));
+ ThreadState *thr = cur_thread();
+ thr->external_tag = (uptr)tag;
+ if (caller_pc) FuncEntry(thr, (uptr)caller_pc);
+ bool in_ignored_lib;
+ if (!caller_pc || !libignore()->IsIgnored((uptr)caller_pc, &in_ignored_lib)) {
+ access(thr, CALLERPC, (uptr)addr, kSizeLog1);
+ }
+ if (caller_pc) FuncExit(thr);
+ thr->external_tag = 0;
+}
+
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE
void *__tsan_external_register_tag(const char *object_type) {
@@ -54,24 +69,12 @@ void __tsan_external_assign_tag(void *addr, void *tag) {
SANITIZER_INTERFACE_ATTRIBUTE
void __tsan_external_read(void *addr, void *caller_pc, void *tag) {
- CHECK_LT(tag, atomic_load(&used_tags, memory_order_relaxed));
- ThreadState *thr = cur_thread();
- thr->external_tag = (uptr)tag;
- FuncEntry(thr, (uptr)caller_pc);
- MemoryRead(thr, CALLERPC, (uptr)addr, kSizeLog8);
- FuncExit(thr);
- thr->external_tag = 0;
+ ExternalAccess(addr, caller_pc, tag, MemoryRead);
}
SANITIZER_INTERFACE_ATTRIBUTE
void __tsan_external_write(void *addr, void *caller_pc, void *tag) {
- CHECK_LT(tag, atomic_load(&used_tags, memory_order_relaxed));
- ThreadState *thr = cur_thread();
- thr->external_tag = (uptr)tag;
- FuncEntry(thr, (uptr)caller_pc);
- MemoryWrite(thr, CALLERPC, (uptr)addr, kSizeLog8);
- FuncExit(thr);
- thr->external_tag = 0;
+ ExternalAccess(addr, caller_pc, tag, MemoryWrite);
}
} // extern "C"
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc
index d0fd91aec234a..334cc326daf6c 100644
--- a/lib/tsan/rtl/tsan_interceptors.cc
+++ b/lib/tsan/rtl/tsan_interceptors.cc
@@ -210,7 +210,7 @@ struct ThreadSignalContext {
// The object is 64-byte aligned, because we want hot data to be located in
// a single cache line if possible (it's accessed in every interceptor).
static ALIGNED(64) char libignore_placeholder[sizeof(LibIgnore)];
-static LibIgnore *libignore() {
+LibIgnore *libignore() {
return reinterpret_cast<LibIgnore*>(&libignore_placeholder[0]);
}
@@ -269,6 +269,7 @@ ScopedInterceptor::~ScopedInterceptor() {
void ScopedInterceptor::EnableIgnores() {
if (ignoring_) {
ThreadIgnoreBegin(thr_, pc_, false);
+ if (flags()->ignore_noninstrumented_modules) thr_->suppress_reports++;
if (in_ignored_lib_) {
DCHECK(!thr_->in_ignored_lib);
thr_->in_ignored_lib = true;
@@ -279,6 +280,7 @@ void ScopedInterceptor::EnableIgnores() {
void ScopedInterceptor::DisableIgnores() {
if (ignoring_) {
ThreadIgnoreEnd(thr_, pc_);
+ if (flags()->ignore_noninstrumented_modules) thr_->suppress_reports--;
if (in_ignored_lib_) {
DCHECK(thr_->in_ignored_lib);
thr_->in_ignored_lib = false;
diff --git a/lib/tsan/rtl/tsan_interceptors.h b/lib/tsan/rtl/tsan_interceptors.h
index 72534f4a24a64..de47466501da7 100644
--- a/lib/tsan/rtl/tsan_interceptors.h
+++ b/lib/tsan/rtl/tsan_interceptors.h
@@ -19,6 +19,8 @@ class ScopedInterceptor {
bool ignoring_;
};
+LibIgnore *libignore();
+
} // namespace __tsan
#define SCOPED_INTERCEPTOR_RAW(func, ...) \
diff --git a/lib/tsan/rtl/tsan_report.cc b/lib/tsan/rtl/tsan_report.cc
index 7de00840cdbce..af5fe61761d79 100644
--- a/lib/tsan/rtl/tsan_report.cc
+++ b/lib/tsan/rtl/tsan_report.cc
@@ -169,7 +169,7 @@ static void PrintMop(const ReportMop *mop, bool first) {
MopDesc(first, mop->write, mop->atomic), mop->size,
(void *)mop->addr, thread_name(thrbuf, mop->tid));
} else {
- Printf(" %s access of object %s at %p by %s",
+ Printf(" %s access of %s at %p by %s",
ExternalMopDesc(first, mop->write), object_type,
(void *)mop->addr, thread_name(thrbuf, mop->tid));
}
@@ -202,7 +202,7 @@ static void PrintLocation(const ReportLocation *loc) {
loc->heap_chunk_size, loc->heap_chunk_start,
thread_name(thrbuf, loc->tid));
} else {
- Printf(" Location is %s object of size %zu at %p allocated by %s:\n",
+ Printf(" Location is %s of size %zu at %p allocated by %s:\n",
object_type, loc->heap_chunk_size, loc->heap_chunk_start,
thread_name(thrbuf, loc->tid));
}
diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h
index 3481c31ebb1c3..09c97a3a4f3d1 100644
--- a/lib/tsan/rtl/tsan_rtl.h
+++ b/lib/tsan/rtl/tsan_rtl.h
@@ -381,6 +381,7 @@ struct ThreadState {
// for better performance.
int ignore_reads_and_writes;
int ignore_sync;
+ int suppress_reports;
// Go does not support ignores.
#if !SANITIZER_GO
IgnoreSet mop_ignore_set;
diff --git a/lib/tsan/rtl/tsan_rtl_report.cc b/lib/tsan/rtl/tsan_rtl_report.cc
index 31b9e97898b01..5cd93a184ce76 100644
--- a/lib/tsan/rtl/tsan_rtl_report.cc
+++ b/lib/tsan/rtl/tsan_rtl_report.cc
@@ -500,7 +500,7 @@ static void AddRacyStacks(ThreadState *thr, VarSizeStackTrace traces[2],
}
bool OutputReport(ThreadState *thr, const ScopedReport &srep) {
- if (!flags()->report_bugs)
+ if (!flags()->report_bugs || thr->suppress_reports)
return false;
atomic_store_relaxed(&ctx->last_symbolize_time_ns, NanoTime());
const ReportDesc *rep = srep.GetReport();