[compiler-rt] r184957 - [tsan] Move some suppressions-related code to common.

Sergey Matveev earthdok at google.com
Wed Jun 26 08:37:14 PDT 2013


Author: smatveev
Date: Wed Jun 26 10:37:14 2013
New Revision: 184957

URL: http://llvm.org/viewvc/llvm-project?rev=184957&view=rev
Log:
[tsan] Move some suppressions-related code to common.

Factor out code to be reused in LSan. Also switch from linked list to vector.

Added:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h
    compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
Removed:
    compiler-rt/trunk/lib/tsan/tests/unit/tsan_suppressions_test.cc
Modified:
    compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
    compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt
    compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h
    compiler-rt/trunk/lib/tsan/tests/unit/CMakeLists.txt

Modified: compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt?rev=184957&r1=184956&r2=184957&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt Wed Jun 26 10:37:14 2013
@@ -13,6 +13,7 @@ set(SANITIZER_SOURCES
   sanitizer_printf.cc
   sanitizer_stackdepot.cc
   sanitizer_stacktrace.cc
+  sanitizer_suppressions.cc
   sanitizer_symbolizer_itanium.cc
   sanitizer_symbolizer_linux.cc
   sanitizer_symbolizer_mac.cc

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc?rev=184957&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc Wed Jun 26 10:37:14 2013
@@ -0,0 +1,131 @@
+//===-- sanitizer_suppressions.cc -----------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Suppression parsing/matching code shared between TSan and LSan.
+//
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_suppressions.h"
+
+#include "sanitizer_allocator_internal.h"
+#include "sanitizer_common.h"
+#include "sanitizer_libc.h"
+
+namespace __sanitizer {
+
+static const char *const kTypeStrings[SuppressionTypeCount] = {
+  "none", "race", "mutex", "thread", "signal"
+};
+
+bool TemplateMatch(char *templ, const char *str) {
+  if (str == 0 || str[0] == 0)
+    return false;
+  char *tpos;
+  const char *spos;
+  while (templ && templ[0]) {
+    if (templ[0] == '*') {
+      templ++;
+      continue;
+    }
+    if (str[0] == 0)
+      return false;
+    tpos = (char*)internal_strchr(templ, '*');
+    if (tpos != 0)
+      tpos[0] = 0;
+    spos = internal_strstr(str, templ);
+    str = spos + internal_strlen(templ);
+    templ = tpos;
+    if (tpos)
+      tpos[0] = '*';
+    if (spos == 0)
+      return false;
+  }
+  return true;
+}
+
+bool SuppressionContext::Match(const char *str, SuppressionType type,
+                               Suppression **s) {
+  can_parse_ = false;
+  uptr i;
+  for (i = 0; i < suppressions_.size(); i++)
+    if (type == suppressions_[i].type &&
+        TemplateMatch(suppressions_[i].templ, str))
+      break;
+  if (i == suppressions_.size()) return false;
+  *s = &suppressions_[i];
+  return true;
+}
+
+static const char *StripPrefix(const char *str, const char *prefix) {
+  while (str && *str == *prefix) {
+    str++;
+    prefix++;
+  }
+  if (!*prefix)
+    return str;
+  return 0;
+}
+
+void SuppressionContext::Parse(const char *str) {
+  // Context must not mutate once Match has been called.
+  CHECK(can_parse_);
+  const char *line = str;
+  while (line) {
+    while (line[0] == ' ' || line[0] == '\t')
+      line++;
+    const char *end = internal_strchr(line, '\n');
+    if (end == 0)
+      end = line + internal_strlen(line);
+    if (line != end && line[0] != '#') {
+      const char *end2 = end;
+      while (line != end2 && (end2[-1] == ' ' || end2[-1] == '\t'))
+        end2--;
+      int type;
+      for (type = 0; type < SuppressionTypeCount; type++) {
+        const char *next_char = StripPrefix(line, kTypeStrings[type]);
+        if (next_char && *next_char == ':') {
+          line = ++next_char;
+          break;
+        }
+      }
+      if (type == SuppressionTypeCount) {
+        Printf("%s: failed to parse suppressions file\n", SanitizerToolName);
+        Die();
+      }
+      Suppression s;
+      s.type = static_cast<SuppressionType>(type);
+      s.templ = (char*)InternalAlloc(end2 - line + 1);
+      internal_memcpy(s.templ, line, end2 - line);
+      s.templ[end2 - line] = 0;
+      s.hit_count = 0;
+      suppressions_.push_back(s);
+    }
+    if (end[0] == 0)
+      break;
+    line = end + 1;
+  }
+}
+
+uptr SuppressionContext::SuppressionCount() {
+  return suppressions_.size();
+}
+
+void SuppressionContext::GetMatched(
+    InternalMmapVector<Suppression *> *matched) {
+  for (uptr i = 0; i < suppressions_.size(); i++)
+    if (suppressions_[i].hit_count)
+      matched->push_back(&suppressions_[i]);
+}
+
+const char *SuppressionTypeString(SuppressionType t) {
+  CHECK(t < SuppressionTypeCount);
+  return kTypeStrings[t];
+}
+
+}  // namespace __sanitizer

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h?rev=184957&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h Wed Jun 26 10:37:14 2013
@@ -0,0 +1,58 @@
+//===-- sanitizer_suppressions.h --------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Suppression parsing/matching code shared between TSan and LSan.
+//
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_SUPPRESSIONS_H
+#define SANITIZER_SUPPRESSIONS_H
+
+#include "sanitizer_common.h"
+#include "sanitizer_internal_defs.h"
+
+namespace __sanitizer {
+
+enum SuppressionType {
+  SuppressionNone,
+  SuppressionRace,
+  SuppressionMutex,
+  SuppressionThread,
+  SuppressionSignal,
+  SuppressionTypeCount
+};
+
+struct Suppression {
+  SuppressionType type;
+  char *templ;
+  unsigned hit_count;
+};
+
+class SuppressionContext {
+ public:
+  SuppressionContext() : suppressions_(1), can_parse_(true) {}
+  void Parse(const char *str);
+  bool Match(const char* str, SuppressionType type, Suppression **s);
+  uptr SuppressionCount();
+  void GetMatched(InternalMmapVector<Suppression *> *matched);
+
+ private:
+  InternalMmapVector<Suppression> suppressions_;
+  bool can_parse_;
+
+  friend class SuppressionContextTest;
+};
+
+const char *SuppressionTypeString(SuppressionType t);
+
+// Exposed for testing.
+bool TemplateMatch(char *templ, const char *str);
+
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_SUPPRESSIONS_H

Modified: compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt?rev=184957&r1=184956&r2=184957&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt Wed Jun 26 10:37:14 2013
@@ -16,6 +16,7 @@ set(SANITIZER_UNITTESTS
   sanitizer_stackdepot_test.cc
   sanitizer_stacktrace_test.cc
   sanitizer_stoptheworld_test.cc
+  sanitizer_suppressions_test.cc
   sanitizer_test_main.cc
   sanitizer_thread_registry_test.cc
   )

Added: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc?rev=184957&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc Wed Jun 26 10:37:14 2013
@@ -0,0 +1,130 @@
+//===-- sanitizer_suppressions_test.cc ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_suppressions.h"
+#include "gtest/gtest.h"
+
+#include <string.h>
+
+namespace __sanitizer {
+
+static bool MyMatch(const char *templ, const char *func) {
+  char tmp[1024];
+  strcpy(tmp, templ);  // NOLINT
+  return TemplateMatch(tmp, func);
+}
+
+TEST(Suppressions, Match) {
+  EXPECT_TRUE(MyMatch("foobar", "foobar"));
+  EXPECT_TRUE(MyMatch("foobar", "prefix_foobar_postfix"));
+  EXPECT_TRUE(MyMatch("*foobar*", "prefix_foobar_postfix"));
+  EXPECT_TRUE(MyMatch("foo*bar", "foo_middle_bar"));
+  EXPECT_TRUE(MyMatch("foo*bar", "foobar"));
+  EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_bar_another_baz"));
+  EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_barbaz"));
+
+  EXPECT_FALSE(MyMatch("foo", "baz"));
+  EXPECT_FALSE(MyMatch("foobarbaz", "foobar"));
+  EXPECT_FALSE(MyMatch("foobarbaz", "barbaz"));
+  EXPECT_FALSE(MyMatch("foo*bar", "foobaz"));
+  EXPECT_FALSE(MyMatch("foo*bar", "foo_baz"));
+}
+
+TEST(Suppressions, TypeStrings) {
+  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionNone), "none"));
+  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionRace), "race"));
+  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionMutex), "mutex"));
+  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionThread), "thread"));
+  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionSignal), "signal"));
+  // Ensure this test is up-to-date when suppression types are added.
+  CHECK_EQ(SuppressionTypeCount, 5);
+}
+
+class SuppressionContextTest : public ::testing::Test {
+ public:
+  virtual void SetUp() { ctx_ = new(placeholder_) SuppressionContext; }
+  virtual void TearDown() { ctx_->~SuppressionContext(); }
+
+ protected:
+  InternalMmapVector<Suppression> *Suppressions() {
+    return &ctx_->suppressions_;
+  }
+  SuppressionContext *ctx_;
+  ALIGNED(64) char placeholder_[sizeof(SuppressionContext)];
+};
+
+TEST_F(SuppressionContextTest, Parse) {
+  ctx_->Parse(
+    "race:foo\n"
+    " 	race:bar\n"  // NOLINT
+    "race:baz	 \n"  // NOLINT
+    "# a comment\n"
+    "race:quz\n"
+  );  // NOLINT
+  EXPECT_EQ((unsigned)4, ctx_->SuppressionCount());
+  EXPECT_EQ((*Suppressions())[3].type, SuppressionRace);
+  EXPECT_EQ(0, strcmp((*Suppressions())[3].templ, "quz"));
+  EXPECT_EQ((*Suppressions())[2].type, SuppressionRace);
+  EXPECT_EQ(0, strcmp((*Suppressions())[2].templ, "baz"));
+  EXPECT_EQ((*Suppressions())[1].type, SuppressionRace);
+  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar"));
+  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
+  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo"));
+}
+
+TEST_F(SuppressionContextTest, Parse2) {
+  ctx_->Parse(
+    "  	# first line comment\n"  // NOLINT
+    " 	race:bar 	\n"  // NOLINT
+    "race:baz* *baz\n"
+    "# a comment\n"
+    "# last line comment\n"
+  );  // NOLINT
+  EXPECT_EQ((unsigned)2, ctx_->SuppressionCount());
+  EXPECT_EQ((*Suppressions())[1].type, SuppressionRace);
+  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "baz* *baz"));
+  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
+  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "bar"));
+}
+
+TEST_F(SuppressionContextTest, Parse3) {
+  ctx_->Parse(
+    "# last suppression w/o line-feed\n"
+    "race:foo\n"
+    "race:bar"
+  );  // NOLINT
+  EXPECT_EQ((unsigned)2, ctx_->SuppressionCount());
+  EXPECT_EQ((*Suppressions())[1].type, SuppressionRace);
+  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar"));
+  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
+  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo"));
+}
+
+TEST_F(SuppressionContextTest, ParseType) {
+  ctx_->Parse(
+    "race:foo\n"
+    "thread:bar\n"
+    "mutex:baz\n"
+    "signal:quz\n"
+  );  // NOLINT
+  EXPECT_EQ((unsigned)4, ctx_->SuppressionCount());
+  EXPECT_EQ((*Suppressions())[3].type, SuppressionSignal);
+  EXPECT_EQ(0, strcmp((*Suppressions())[3].templ, "quz"));
+  EXPECT_EQ((*Suppressions())[2].type, SuppressionMutex);
+  EXPECT_EQ(0, strcmp((*Suppressions())[2].templ, "baz"));
+  EXPECT_EQ((*Suppressions())[1].type, SuppressionThread);
+  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar"));
+  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
+  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo"));
+}
+
+}  // namespace __sanitizer

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h?rev=184957&r1=184956&r2=184957&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h Wed Jun 26 10:37:14 2013
@@ -162,7 +162,6 @@ class ReportDesc;
 class RegionAlloc;
 class StackTrace;
 struct MBlock;
-struct Suppression;
 
 }  // namespace __tsan
 

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=184957&r1=184956&r2=184957&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Wed Jun 26 10:37:14 2013
@@ -29,6 +29,7 @@
 #include "sanitizer_common/sanitizer_allocator.h"
 #include "sanitizer_common/sanitizer_allocator_internal.h"
 #include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_suppressions.h"
 #include "sanitizer_common/sanitizer_thread_registry.h"
 #include "tsan_clock.h"
 #include "tsan_defs.h"

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=184957&r1=184956&r2=184957&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc Wed Jun 26 10:37:14 2013
@@ -13,6 +13,8 @@
 
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_libc.h"
+#include "sanitizer_common/sanitizer_placement_new.h"
+#include "sanitizer_common/sanitizer_suppressions.h"
 #include "tsan_suppressions.h"
 #include "tsan_rtl.h"
 #include "tsan_flags.h"
@@ -28,7 +30,7 @@ extern "C" const char *WEAK __tsan_defau
 
 namespace __tsan {
 
-static Suppression *g_suppressions;
+static SuppressionContext* g_ctx;
 
 static char *ReadFile(const char *filename) {
   if (filename == 0 || filename[0] == 0)
@@ -62,87 +64,14 @@ static char *ReadFile(const char *filena
   return buf;
 }
 
-bool SuppressionMatch(char *templ, const char *str) {
-  if (str == 0 || str[0] == 0)
-    return false;
-  char *tpos;
-  const char *spos;
-  while (templ && templ[0]) {
-    if (templ[0] == '*') {
-      templ++;
-      continue;
-    }
-    if (str[0] == 0)
-      return false;
-    tpos = (char*)internal_strchr(templ, '*');
-    if (tpos != 0)
-      tpos[0] = 0;
-    spos = internal_strstr(str, templ);
-    str = spos + internal_strlen(templ);
-    templ = tpos;
-    if (tpos)
-      tpos[0] = '*';
-    if (spos == 0)
-      return false;
-  }
-  return true;
-}
-
-Suppression *SuppressionParse(Suppression *head, const char* supp) {
-  const char *line = supp;
-  while (line) {
-    while (line[0] == ' ' || line[0] == '\t')
-      line++;
-    const char *end = internal_strchr(line, '\n');
-    if (end == 0)
-      end = line + internal_strlen(line);
-    if (line != end && line[0] != '#') {
-      const char *end2 = end;
-      while (line != end2 && (end2[-1] == ' ' || end2[-1] == '\t'))
-        end2--;
-      SuppressionType stype;
-      if (0 == internal_strncmp(line, "race:", sizeof("race:") - 1)) {
-        stype = SuppressionRace;
-        line += sizeof("race:") - 1;
-      } else if (0 == internal_strncmp(line, "thread:",
-          sizeof("thread:") - 1)) {
-        stype = SuppressionThread;
-        line += sizeof("thread:") - 1;
-      } else if (0 == internal_strncmp(line, "mutex:",
-          sizeof("mutex:") - 1)) {
-        stype = SuppressionMutex;
-        line += sizeof("mutex:") - 1;
-      } else if (0 == internal_strncmp(line, "signal:",
-          sizeof("signal:") - 1)) {
-        stype = SuppressionSignal;
-        line += sizeof("signal:") - 1;
-      } else {
-        Printf("ThreadSanitizer: failed to parse suppressions file\n");
-        Die();
-      }
-      Suppression *s = (Suppression*)internal_alloc(MBlockSuppression,
-          sizeof(Suppression));
-      s->next = head;
-      head = s;
-      s->type = stype;
-      s->templ = (char*)internal_alloc(MBlockSuppression, end2 - line + 1);
-      internal_memcpy(s->templ, line, end2 - line);
-      s->templ[end2 - line] = 0;
-      s->hit_count = 0;
-    }
-    if (end[0] == 0)
-      break;
-    line = end + 1;
-  }
-  return head;
-}
-
 void InitializeSuppressions() {
+  ALIGNED(64) static char placeholder_[sizeof(SuppressionContext)];
+  g_ctx = new(placeholder_) SuppressionContext;
   const char *supp = ReadFile(flags()->suppressions);
-  g_suppressions = SuppressionParse(0, supp);
+  g_ctx->Parse(supp);
 #ifndef TSAN_GO
   supp = __tsan_default_suppressions();
-  g_suppressions = SuppressionParse(g_suppressions, supp);
+  g_ctx->Parse(supp);
 #endif
 }
 
@@ -166,71 +95,59 @@ SuppressionType conv(ReportType typ) {
 }
 
 uptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp) {
-  if (g_suppressions == 0 || stack == 0)
-    return 0;
+  CHECK(g_ctx);
+  if (!g_ctx->SuppressionCount() || stack == 0) return 0;
   SuppressionType stype = conv(typ);
   if (stype == SuppressionNone)
     return 0;
+  Suppression *s;
   for (const ReportStack *frame = stack; frame; frame = frame->next) {
-    for (Suppression *supp = g_suppressions; supp; supp = supp->next) {
-      if (stype == supp->type &&
-          (SuppressionMatch(supp->templ, frame->func) ||
-           SuppressionMatch(supp->templ, frame->file) ||
-           SuppressionMatch(supp->templ, frame->module))) {
-        DPrintf("ThreadSanitizer: matched suppression '%s'\n", supp->templ);
-        supp->hit_count++;
-        *sp = supp;
-        return frame->pc;
-      }
+    if (g_ctx->Match(frame->func, stype, &s) ||
+        g_ctx->Match(frame->file, stype, &s) ||
+        g_ctx->Match(frame->module, stype, &s)) {
+      DPrintf("ThreadSanitizer: matched suppression '%s'\n", s->templ);
+      s->hit_count++;
+      *sp = s;
+      return frame->pc;
     }
   }
   return 0;
 }
 
 uptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp) {
-  if (g_suppressions == 0 || loc == 0 || loc->type != ReportLocationGlobal)
+  CHECK(g_ctx);
+  if (!g_ctx->SuppressionCount() || 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;
+  Suppression *s;
+  if (g_ctx->Match(loc->name, stype, &s) ||
+      g_ctx->Match(loc->file, stype, &s) ||
+      g_ctx->Match(loc->module, stype, &s)) {
+      DPrintf("ThreadSanitizer: matched suppression '%s'\n", templ);
+      s->hit_count++;
+      *sp = s;
       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";
-  case SuppressionSignal: return "signal";
-  }
-  CHECK(0);
-  return "unknown";
-}
-
 void PrintMatchedSuppressions() {
-  int hit_count = 0;
-  for (Suppression *supp = g_suppressions; supp; supp = supp->next)
-    hit_count += supp->hit_count;
-  if (hit_count == 0)
+  CHECK(g_ctx);
+  InternalMmapVector<Suppression *> matched(1);
+  g_ctx->GetMatched(&matched);
+  if (!matched.size())
     return;
-  Printf("ThreadSanitizer: Matched %d suppressions (pid=%d):\n",
-      hit_count, (int)internal_getpid());
-  for (Suppression *supp = g_suppressions; supp; supp = supp->next) {
-    if (supp->hit_count == 0)
-      continue;
-    Printf("%d %s:%s\n", supp->hit_count, SuppTypeStr(supp->type), supp->templ);
+  int hit_count = 0;
+  for (uptr i = 0; i < matched.size(); i++)
+    hit_count += matched[i]->hit_count;
+  Printf("ThreadSanitizer: Matched %d suppressions (pid=%d):\n", hit_count,
+         (int)internal_getpid());
+  for (uptr i = 0; i < matched.size(); i++) {
+    Printf("%d %s:%s\n", matched[i]->hit_count,
+           SuppressionTypeString(matched[i]->type), matched[i]->templ);
   }
 }
 }  // namespace __tsan

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=184957&r1=184956&r2=184957&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h Wed Jun 26 10:37:14 2013
@@ -13,33 +13,15 @@
 #ifndef TSAN_SUPPRESSIONS_H
 #define TSAN_SUPPRESSIONS_H
 
+#include "sanitizer_common/sanitizer_suppressions.h"
 #include "tsan_report.h"
 
 namespace __tsan {
 
-// Exposed for testing.
-enum SuppressionType {
-  SuppressionNone,
-  SuppressionRace,
-  SuppressionMutex,
-  SuppressionThread,
-  SuppressionSignal
-};
-
-struct Suppression {
-  Suppression *next;
-  SuppressionType type;
-  char *templ;
-  int hit_count;
-};
-
 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);
 
 }  // namespace __tsan
 

Modified: compiler-rt/trunk/lib/tsan/tests/unit/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/unit/CMakeLists.txt?rev=184957&r1=184956&r2=184957&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/unit/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/tsan/tests/unit/CMakeLists.txt Wed Jun 26 10:37:14 2013
@@ -5,7 +5,6 @@ set(TSAN_UNIT_TESTS
   tsan_mutex_test.cc
   tsan_shadow_test.cc
   tsan_stack_test.cc
-  tsan_suppressions_test.cc
   tsan_sync_test.cc
   tsan_vector_test.cc
   )

Removed: compiler-rt/trunk/lib/tsan/tests/unit/tsan_suppressions_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/unit/tsan_suppressions_test.cc?rev=184956&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/unit/tsan_suppressions_test.cc (original)
+++ compiler-rt/trunk/lib/tsan/tests/unit/tsan_suppressions_test.cc (removed)
@@ -1,128 +0,0 @@
-//===-- tsan_suppressions_test.cc -----------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_suppressions.h"
-#include "tsan_rtl.h"
-#include "gtest/gtest.h"
-
-#include <string.h>
-
-namespace __tsan {
-
-TEST(Suppressions, Parse) {
-  ScopedInRtl in_rtl;
-  Suppression *supp0 = SuppressionParse(0,
-    "race:foo\n"
-    " 	race:bar\n"  // NOLINT
-    "race:baz	 \n"  // NOLINT
-    "# a comment\n"
-    "race:quz\n"
-  );  // NOLINT
-  Suppression *supp = supp0;
-  EXPECT_EQ(supp->type, SuppressionRace);
-  EXPECT_EQ(0, strcmp(supp->templ, "quz"));
-  supp = supp->next;
-  EXPECT_EQ(supp->type, SuppressionRace);
-  EXPECT_EQ(0, strcmp(supp->templ, "baz"));
-  supp = supp->next;
-  EXPECT_EQ(supp->type, SuppressionRace);
-  EXPECT_EQ(0, strcmp(supp->templ, "bar"));
-  supp = supp->next;
-  EXPECT_EQ(supp->type, SuppressionRace);
-  EXPECT_EQ(0, strcmp(supp->templ, "foo"));
-  supp = supp->next;
-  EXPECT_EQ((Suppression*)0, supp);
-}
-
-TEST(Suppressions, Parse2) {
-  ScopedInRtl in_rtl;
-  Suppression *supp0 = SuppressionParse(0,
-    "  	# first line comment\n"  // NOLINT
-    " 	race:bar 	\n"  // NOLINT
-    "race:baz* *baz\n"
-    "# a comment\n"
-    "# last line comment\n"
-  );  // NOLINT
-  Suppression *supp = supp0;
-  EXPECT_EQ(supp->type, SuppressionRace);
-  EXPECT_EQ(0, strcmp(supp->templ, "baz* *baz"));
-  supp = supp->next;
-  EXPECT_EQ(supp->type, SuppressionRace);
-  EXPECT_EQ(0, strcmp(supp->templ, "bar"));
-  supp = supp->next;
-  EXPECT_EQ((Suppression*)0, supp);
-}
-
-TEST(Suppressions, Parse3) {
-  ScopedInRtl in_rtl;
-  Suppression *supp0 = SuppressionParse(0,
-    "# last suppression w/o line-feed\n"
-    "race:foo\n"
-    "race:bar"
-  );  // NOLINT
-  Suppression *supp = supp0;
-  EXPECT_EQ(supp->type, SuppressionRace);
-  EXPECT_EQ(0, strcmp(supp->templ, "bar"));
-  supp = supp->next;
-  EXPECT_EQ(supp->type, SuppressionRace);
-  EXPECT_EQ(0, strcmp(supp->templ, "foo"));
-  supp = supp->next;
-  EXPECT_EQ((Suppression*)0, supp);
-}
-
-TEST(Suppressions, ParseType) {
-  ScopedInRtl in_rtl;
-  Suppression *supp0 = SuppressionParse(0,
-    "race:foo\n"
-    "thread:bar\n"
-    "mutex:baz\n"
-    "signal:quz\n"
-  );  // NOLINT
-  Suppression *supp = supp0;
-  EXPECT_EQ(supp->type, SuppressionSignal);
-  EXPECT_EQ(0, strcmp(supp->templ, "quz"));
-  supp = supp->next;
-  EXPECT_EQ(supp->type, SuppressionMutex);
-  EXPECT_EQ(0, strcmp(supp->templ, "baz"));
-  supp = supp->next;
-  EXPECT_EQ(supp->type, SuppressionThread);
-  EXPECT_EQ(0, strcmp(supp->templ, "bar"));
-  supp = supp->next;
-  EXPECT_EQ(supp->type, SuppressionRace);
-  EXPECT_EQ(0, strcmp(supp->templ, "foo"));
-  supp = supp->next;
-  EXPECT_EQ((Suppression*)0, supp);
-}
-
-static bool MyMatch(const char *templ, const char *func) {
-  char tmp[1024];
-  strcpy(tmp, templ);  // NOLINT
-  return SuppressionMatch(tmp, func);
-}
-
-TEST(Suppressions, Match) {
-  EXPECT_TRUE(MyMatch("foobar", "foobar"));
-  EXPECT_TRUE(MyMatch("foobar", "prefix_foobar_postfix"));
-  EXPECT_TRUE(MyMatch("*foobar*", "prefix_foobar_postfix"));
-  EXPECT_TRUE(MyMatch("foo*bar", "foo_middle_bar"));
-  EXPECT_TRUE(MyMatch("foo*bar", "foobar"));
-  EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_bar_another_baz"));
-  EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_barbaz"));
-
-  EXPECT_FALSE(MyMatch("foo", "baz"));
-  EXPECT_FALSE(MyMatch("foobarbaz", "foobar"));
-  EXPECT_FALSE(MyMatch("foobarbaz", "barbaz"));
-  EXPECT_FALSE(MyMatch("foo*bar", "foobaz"));
-  EXPECT_FALSE(MyMatch("foo*bar", "foo_baz"));
-}
-
-}  // namespace __tsan





More information about the llvm-commits mailing list