[compiler-rt] r183672 - tsan: allows to suppress races on global variables
Dmitry Vyukov
dvyukov at google.com
Mon Jun 10 08:38:44 PDT 2013
Author: dvyukov
Date: Mon Jun 10 10:38:44 2013
New Revision: 183672
URL: http://llvm.org/viewvc/llvm-project?rev=183672&view=rev
Log:
tsan: allows to suppress races on global variables
Modified:
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=183672&r1=183671&r2=183672&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Mon Jun 10 10:38:44 2013
@@ -602,7 +602,8 @@ void ReportRace(ThreadState *thr);
bool OutputReport(Context *ctx,
const ScopedReport &srep,
const ReportStack *suppress_stack1 = 0,
- const ReportStack *suppress_stack2 = 0);
+ const ReportStack *suppress_stack2 = 0,
+ const ReportLocation *suppress_loc = 0);
bool IsFiredSuppression(Context *ctx,
const ScopedReport &srep,
const StackTrace &trace);
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=183672&r1=183671&r2=183672&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc Mon Jun 10 10:38:44 2013
@@ -502,13 +502,16 @@ static void AddRacyStacks(ThreadState *t
bool OutputReport(Context *ctx,
const ScopedReport &srep,
const ReportStack *suppress_stack1,
- const ReportStack *suppress_stack2) {
+ const ReportStack *suppress_stack2,
+ const ReportLocation *suppress_loc) {
atomic_store(&ctx->last_symbolize_time_ns, NanoTime(), memory_order_relaxed);
const ReportDesc *rep = srep.GetReport();
Suppression *supp = 0;
uptr suppress_pc = IsSuppressed(rep->typ, suppress_stack1, &supp);
if (suppress_pc == 0)
suppress_pc = IsSuppressed(rep->typ, suppress_stack2, &supp);
+ if (suppress_pc == 0)
+ suppress_pc = IsSuppressed(rep->typ, suppress_loc, &supp);
if (suppress_pc != 0) {
FiredSuppression s = {srep.GetReport()->typ, suppress_pc, supp};
ctx->fired_suppressions.PushBack(s);
@@ -538,6 +541,22 @@ bool IsFiredSuppression(Context *ctx,
return false;
}
+static bool IsFiredSuppression(Context *ctx,
+ const ScopedReport &srep,
+ uptr addr) {
+ for (uptr k = 0; k < ctx->fired_suppressions.Size(); k++) {
+ if (ctx->fired_suppressions[k].type != srep.GetReport()->typ)
+ continue;
+ FiredSuppression *s = &ctx->fired_suppressions[k];
+ if (addr == s->pc) {
+ if (s->supp)
+ s->supp->hit_count++;
+ return true;
+ }
+ }
+ return false;
+}
+
bool FrameIsInternal(const ReportStack *frame) {
return frame != 0 && frame->file != 0
&& (internal_strstr(frame->file, "tsan_interceptors.cc") ||
@@ -631,6 +650,8 @@ void ReportRace(ThreadState *thr) {
else if (freed)
typ = ReportTypeUseAfterFree;
ScopedReport rep(typ);
+ if (IsFiredSuppression(ctx, rep, addr))
+ return;
const uptr kMop = 2;
StackTrace traces[kMop];
const uptr toppc = TraceTopPC(thr);
@@ -641,6 +662,8 @@ void ReportRace(ThreadState *thr) {
new(mset2.data()) MutexSet();
Shadow s2(thr->racy_state[1]);
RestoreStack(s2.tid(), s2.epoch(), &traces[1], mset2.data());
+ if (IsFiredSuppression(ctx, rep, traces[1]))
+ return;
if (HandleRacyStacks(thr, traces, addr_min, addr_max))
return;
@@ -673,8 +696,11 @@ void ReportRace(ThreadState *thr) {
}
#endif
+ ReportLocation *suppress_loc = rep.GetReport()->locs.Size() ?
+ rep.GetReport()->locs[0] : 0;
if (!OutputReport(ctx, rep, rep.GetReport()->mops[0]->stack,
- rep.GetReport()->mops[1]->stack))
+ rep.GetReport()->mops[1]->stack,
+ suppress_loc))
return;
AddRacyStacks(thr, traces, addr_min, addr_max);
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc?rev=183672&r1=183671&r2=183672&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc Mon Jun 10 10:38:44 2013
@@ -146,26 +146,31 @@ void InitializeSuppressions() {
#endif
}
-uptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp) {
- if (g_suppressions == 0 || stack == 0)
- return 0;
- SuppressionType stype;
+SuppressionType conv(ReportType typ) {
if (typ == ReportTypeRace)
- stype = SuppressionRace;
+ return SuppressionRace;
else if (typ == ReportTypeVptrRace)
- stype = SuppressionRace;
+ return SuppressionRace;
else if (typ == ReportTypeUseAfterFree)
- return 0;
+ return SuppressionNone;
else if (typ == ReportTypeThreadLeak)
- stype = SuppressionThread;
+ return SuppressionThread;
else if (typ == ReportTypeMutexDestroyLocked)
- stype = SuppressionMutex;
+ return SuppressionMutex;
else if (typ == ReportTypeSignalUnsafe)
- stype = SuppressionSignal;
+ return SuppressionSignal;
else if (typ == ReportTypeErrnoInSignal)
+ return SuppressionNone;
+ Printf("ThreadSanitizer: unknown report type %d\n", typ),
+ Die();
+}
+
+uptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp) {
+ if (g_suppressions == 0 || stack == 0)
+ return 0;
+ SuppressionType stype = conv(typ);
+ if (stype == SuppressionNone)
return 0;
- else
- Printf("ThreadSanitizer: unknown report type %d\n", typ), Die();
for (const ReportStack *frame = stack; frame; frame = frame->next) {
for (Suppression *supp = g_suppressions; supp; supp = supp->next) {
if (stype == supp->type &&
@@ -182,8 +187,29 @@ uptr IsSuppressed(ReportType typ, const
return 0;
}
+uptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp) {
+ if (g_suppressions == 0 || loc == 0 || loc->type != ReportLocationGlobal)
+ return 0;
+ SuppressionType stype = conv(typ);
+ if (stype == SuppressionNone)
+ return 0;
+ for (Suppression *supp = g_suppressions; supp; supp = supp->next) {
+ if (stype == supp->type &&
+ (SuppressionMatch(supp->templ, loc->name) ||
+ SuppressionMatch(supp->templ, loc->file) ||
+ SuppressionMatch(supp->templ, loc->module))) {
+ DPrintf("ThreadSanitizer: matched suppression '%s'\n", supp->templ);
+ supp->hit_count++;
+ *sp = supp;
+ return loc->addr;
+ }
+ }
+ return 0;
+}
+
static const char *SuppTypeStr(SuppressionType t) {
switch (t) {
+ case SuppressionNone: return "none";
case SuppressionRace: return "race";
case SuppressionMutex: return "mutex";
case SuppressionThread: return "thread";
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h?rev=183672&r1=183671&r2=183672&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h Mon Jun 10 10:38:44 2013
@@ -19,6 +19,7 @@ namespace __tsan {
// Exposed for testing.
enum SuppressionType {
+ SuppressionNone,
SuppressionRace,
SuppressionMutex,
SuppressionThread,
@@ -36,6 +37,7 @@ void InitializeSuppressions();
void FinalizeSuppressions();
void PrintMatchedSuppressions();
uptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp);
+uptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp);
Suppression *SuppressionParse(Suppression *head, const char* supp);
bool SuppressionMatch(char *templ, const char *str);
More information about the llvm-commits
mailing list