[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