summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_flags.cc2
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_flags.h2
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc79
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl.cc4
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl.h1
5 files changed, 78 insertions, 10 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.cc b/compiler-rt/lib/tsan/rtl/tsan_flags.cc
index c2ae9d35dee..c062592f482 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_flags.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_flags.cc
@@ -50,6 +50,7 @@ void InitializeFlags(Flags *f, const char *env) {
f->strip_path_prefix = "";
f->suppressions = "";
f->print_suppressions = false;
+ f->print_benign = false;
f->exitcode = 66;
f->log_path = "stderr";
f->atexit_sleep_ms = 1000;
@@ -80,6 +81,7 @@ void InitializeFlags(Flags *f, const char *env) {
ParseFlag(env, &f->strip_path_prefix, "strip_path_prefix");
ParseFlag(env, &f->suppressions, "suppressions");
ParseFlag(env, &f->print_suppressions, "print_suppressions");
+ ParseFlag(env, &f->print_benign, "print_benign");
ParseFlag(env, &f->exitcode, "exitcode");
ParseFlag(env, &f->log_path, "log_path");
ParseFlag(env, &f->atexit_sleep_ms, "atexit_sleep_ms");
diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.h b/compiler-rt/lib/tsan/rtl/tsan_flags.h
index 572d96c3356..aaacd98a622 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_flags.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_flags.h
@@ -54,6 +54,8 @@ struct Flags {
const char *suppressions;
// Print matched suppressions at exit.
bool print_suppressions;
+ // Print matched "benign" races at exit.
+ bool print_benign;
// Override exit status if something was reported.
int exitcode;
// Write logs to "log_path.pid".
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc b/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc
index 51ebbf2266d..f845d8db6cd 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc
@@ -20,6 +20,7 @@
#include "tsan_mman.h"
#include "tsan_flags.h"
#include "tsan_platform.h"
+#include "tsan_vector.h"
#define CALLERPC ((uptr)__builtin_return_address(0))
@@ -67,6 +68,7 @@ struct ExpectRace {
ExpectRace *next;
ExpectRace *prev;
int hitcount;
+ int addcount;
uptr addr;
uptr size;
char *file;
@@ -91,16 +93,19 @@ static void AddExpectRace(ExpectRace *list,
char *f, int l, uptr addr, uptr size, char *desc) {
ExpectRace *race = list->next;
for (; race != list; race = race->next) {
- if (race->addr == addr && race->size == size)
+ if (race->addr == addr && race->size == size) {
+ race->addcount++;
return;
+ }
}
race = (ExpectRace*)internal_alloc(MBlockExpectRace, sizeof(ExpectRace));
- race->hitcount = 0;
race->addr = addr;
race->size = size;
race->file = f;
race->line = l;
race->desc[0] = 0;
+ race->hitcount = 0;
+ race->addcount = 1;
if (desc) {
int i = 0;
for (; i < kMaxDescLen - 1 && desc[i]; i++)
@@ -155,6 +160,68 @@ bool IsExpectedReport(uptr addr, uptr size) {
return false;
}
+static void CollectMatchedBenignRaces(Vector<ExpectRace> *matched,
+ int *unique_count, int *hit_count, int ExpectRace::*counter) {
+ ExpectRace *list = &dyn_ann_ctx->benign;
+ for (ExpectRace *race = list->next; race != list; race = race->next) {
+ (*unique_count)++;
+ if (race->*counter == 0)
+ continue;
+ (*hit_count) += race->*counter;
+ uptr i = 0;
+ for (; i < matched->Size(); i++) {
+ ExpectRace *race0 = &(*matched)[i];
+ if (race->line == race0->line
+ && internal_strcmp(race->file, race0->file) == 0
+ && internal_strcmp(race->desc, race0->desc) == 0) {
+ race0->*counter += race->*counter;
+ break;
+ }
+ }
+ if (i == matched->Size())
+ matched->PushBack(*race);
+ }
+}
+
+void PrintMatchedBenignRaces() {
+ Lock lock(&dyn_ann_ctx->mtx);
+ int unique_count = 0;
+ int hit_count = 0;
+ int add_count = 0;
+ Vector<ExpectRace> hit_matched(MBlockScopedBuf);
+ CollectMatchedBenignRaces(&hit_matched, &unique_count, &hit_count,
+ &ExpectRace::hitcount);
+ Vector<ExpectRace> add_matched(MBlockScopedBuf);
+ CollectMatchedBenignRaces(&add_matched, &unique_count, &add_count,
+ &ExpectRace::addcount);
+ if (hit_matched.Size()) {
+ Printf("ThreadSanitizer: Matched %d \"benign\" races (pid=%d):\n",
+ hit_count, GetPid());
+ for (uptr i = 0; i < hit_matched.Size(); i++) {
+ Printf("%d %s:%d %s\n",
+ hit_matched[i].hitcount, hit_matched[i].file,
+ hit_matched[i].line, hit_matched[i].desc);
+ }
+ }
+ if (hit_matched.Size()) {
+ Printf("ThreadSanitizer: Annotated %d \"benign\" races, %d unique"
+ " (pid=%d):\n",
+ add_count, unique_count, GetPid());
+ for (uptr i = 0; i < add_matched.Size(); i++) {
+ Printf("%d %s:%d %s\n",
+ add_matched[i].addcount, add_matched[i].file,
+ add_matched[i].line, add_matched[i].desc);
+ }
+ }
+}
+
+static void ReportMissedExpectedRace(ExpectRace *race) {
+ Printf("==================\n");
+ Printf("WARNING: ThreadSanitizer: missed expected data race\n");
+ Printf(" %s addr=%zx %s:%d\n",
+ race->desc, race->addr, race->file, race->line);
+ Printf("==================\n");
+}
} // namespace __tsan
using namespace __tsan; // NOLINT
@@ -237,14 +304,6 @@ void INTERFACE_ATTRIBUTE AnnotateNoOp(char *f, int l, uptr mem) {
SCOPED_ANNOTATION(AnnotateNoOp);
}
-static void ReportMissedExpectedRace(ExpectRace *race) {
- Printf("==================\n");
- Printf("WARNING: ThreadSanitizer: missed expected data race\n");
- Printf(" %s addr=%zx %s:%d\n",
- race->desc, race->addr, race->file, race->line);
- Printf("==================\n");
-}
-
void INTERFACE_ATTRIBUTE AnnotateFlushExpectedRaces(char *f, int l) {
SCOPED_ANNOTATION(AnnotateFlushExpectedRaces);
Lock lock(&dyn_ann_ctx->mtx);
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc
index 28113c6cebd..0046dbef969 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc
@@ -279,6 +279,10 @@ int Finalize(ThreadState *thr) {
if (flags()->print_suppressions)
PrintMatchedSuppressions();
+#ifndef TSAN_GO
+ if (flags()->print_benign)
+ PrintMatchedBenignRaces();
+#endif
failed = OnFinalize(failed);
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
index 99dceb46038..b7ec804d8fc 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
@@ -605,6 +605,7 @@ bool IsFiredSuppression(Context *ctx,
const ScopedReport &srep,
const StackTrace &trace);
bool IsExpectedReport(uptr addr, uptr size);
+void PrintMatchedBenignRaces();
bool FrameIsInternal(const ReportStack *frame);
ReportStack *SkipTsanInternalFrames(ReportStack *ent);
OpenPOWER on IntegriCloud