diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2013-03-27 17:59:57 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2013-03-27 17:59:57 +0000 |
commit | b365d40415639411515302f4efb02f836e6ca5d2 (patch) | |
tree | 8415e17027df1175064334041e35a7f55c82b479 /compiler-rt | |
parent | fd3f5ec0cba347eadf9aca6aab5954a018c2eadc (diff) | |
download | bcm5719-llvm-b365d40415639411515302f4efb02f836e6ca5d2.tar.gz bcm5719-llvm-b365d40415639411515302f4efb02f836e6ca5d2.zip |
tsan: print matched suppressions if print_suppressions=1 flag is provided
llvm-svn: 178159
Diffstat (limited to 'compiler-rt')
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_defs.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_flags.cc | 2 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_flags.h | 2 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl.cc | 3 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc | 17 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_suppressions.cc | 31 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_suppressions.h | 9 |
8 files changed, 55 insertions, 11 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_defs.h b/compiler-rt/lib/tsan/rtl/tsan_defs.h index 27f1db38f3a..7150e2e255d 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_defs.h +++ b/compiler-rt/lib/tsan/rtl/tsan_defs.h @@ -162,6 +162,7 @@ class ReportDesc; class RegionAlloc; class StackTrace; struct MBlock; +struct Suppression; } // namespace __tsan diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.cc b/compiler-rt/lib/tsan/rtl/tsan_flags.cc index 722ffdfee0f..c2ae9d35dee 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.cc @@ -49,6 +49,7 @@ void InitializeFlags(Flags *f, const char *env) { f->force_seq_cst_atomics = false; f->strip_path_prefix = ""; f->suppressions = ""; + f->print_suppressions = false; f->exitcode = 66; f->log_path = "stderr"; f->atexit_sleep_ms = 1000; @@ -78,6 +79,7 @@ void InitializeFlags(Flags *f, const char *env) { ParseFlag(env, &f->force_seq_cst_atomics, "force_seq_cst_atomics"); ParseFlag(env, &f->strip_path_prefix, "strip_path_prefix"); ParseFlag(env, &f->suppressions, "suppressions"); + ParseFlag(env, &f->print_suppressions, "print_suppressions"); 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 edeac04d5ac..572d96c3356 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.h +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.h @@ -52,6 +52,8 @@ struct Flags { const char *strip_path_prefix; // Suppressions filename. const char *suppressions; + // Print matched suppressions at exit. + bool print_suppressions; // Override exit status if something was reported. int exitcode; // Write logs to "log_path.pid". diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc index d67c9125f7b..28113c6cebd 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc @@ -277,6 +277,9 @@ int Finalize(ThreadState *thr) { ctx->nmissed_expected); } + if (flags()->print_suppressions) + PrintMatchedSuppressions(); + failed = OnFinalize(failed); StatAggregate(ctx->stat, thr->stat); diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index 80ec3024f3d..99dceb46038 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -512,6 +512,7 @@ struct RacyAddress { struct FiredSuppression { ReportType type; uptr pc; + Suppression *supp; }; struct Context { diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc index fd61f4a43e4..e7109f6e70a 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc @@ -501,12 +501,13 @@ bool OutputReport(Context *ctx, const ReportStack *suppress_stack2) { atomic_store(&ctx->last_symbolize_time_ns, NanoTime(), memory_order_relaxed); const ReportDesc *rep = srep.GetReport(); - uptr suppress_pc = IsSuppressed(rep->typ, suppress_stack1); + Suppression *supp = 0; + uptr suppress_pc = IsSuppressed(rep->typ, suppress_stack1, &supp); if (suppress_pc == 0) - suppress_pc = IsSuppressed(rep->typ, suppress_stack2); + suppress_pc = IsSuppressed(rep->typ, suppress_stack2, &supp); if (suppress_pc != 0) { - FiredSuppression supp = {srep.GetReport()->typ, suppress_pc}; - ctx->fired_suppressions.PushBack(supp); + FiredSuppression s = {srep.GetReport()->typ, suppress_pc, supp}; + ctx->fired_suppressions.PushBack(s); } if (OnReport(rep, suppress_pc != 0)) return false; @@ -522,8 +523,12 @@ bool IsFiredSuppression(Context *ctx, if (ctx->fired_suppressions[k].type != srep.GetReport()->typ) continue; for (uptr j = 0; j < trace.Size(); j++) { - if (trace.Get(j) == ctx->fired_suppressions[k].pc) + FiredSuppression *s = &ctx->fired_suppressions[k]; + if (trace.Get(j) == s->pc) { + if (s->supp) + s->supp->hit_count++; return true; + } } } return false; @@ -560,7 +565,7 @@ static bool IsJavaNonsense(const ReportDesc *rep) { || (frame->func == 0 && frame->file == 0 && frame->line == 0 && frame->module == 0)) { if (frame) { - FiredSuppression supp = {rep->typ, frame->pc}; + FiredSuppression supp = {rep->typ, frame->pc, 0}; CTX()->fired_suppressions.PushBack(supp); } return true; diff --git a/compiler-rt/lib/tsan/rtl/tsan_suppressions.cc b/compiler-rt/lib/tsan/rtl/tsan_suppressions.cc index 941c208aa3e..47fe7b2d4f3 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_suppressions.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_suppressions.cc @@ -127,6 +127,7 @@ Suppression *SuppressionParse(Suppression *head, const char* supp) { 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; @@ -144,7 +145,7 @@ void InitializeSuppressions() { #endif } -uptr IsSuppressed(ReportType typ, const ReportStack *stack) { +uptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp) { if (g_suppressions == 0 || stack == 0) return 0; SuppressionType stype; @@ -165,10 +166,38 @@ uptr IsSuppressed(ReportType typ, const ReportStack *stack) { 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; } } } return 0; } + +static const char *SuppTypeStr(SuppressionType t) { + switch (t) { + 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) + return; + Printf("ThreadSanitizer: Matched %d suppressions (pid=%d):\n", + hit_count, 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); + } +} } // namespace __tsan diff --git a/compiler-rt/lib/tsan/rtl/tsan_suppressions.h b/compiler-rt/lib/tsan/rtl/tsan_suppressions.h index c5883167058..1c98363383d 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_suppressions.h +++ b/compiler-rt/lib/tsan/rtl/tsan_suppressions.h @@ -17,10 +17,6 @@ namespace __tsan { -void InitializeSuppressions(); -void FinalizeSuppressions(); -uptr IsSuppressed(ReportType typ, const ReportStack *stack); - // Exposed for testing. enum SuppressionType { SuppressionRace, @@ -33,8 +29,13 @@ 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); Suppression *SuppressionParse(Suppression *head, const char* supp); bool SuppressionMatch(char *templ, const char *str); |