diff options
| author | Kostya Serebryany <kcc@google.com> | 2014-03-19 12:26:33 +0000 |
|---|---|---|
| committer | Kostya Serebryany <kcc@google.com> | 2014-03-19 12:26:33 +0000 |
| commit | 2ea796e05f586e585f1f62c718245cfed78b0130 (patch) | |
| tree | d8f7b728620c6681dd344960aca256dbfe7b6c31 | |
| parent | e7e8b26f9381f32bc3fca736390ffe7fd6f0f0f2 (diff) | |
| download | bcm5719-llvm-2ea796e05f586e585f1f62c718245cfed78b0130.tar.gz bcm5719-llvm-2ea796e05f586e585f1f62c718245cfed78b0130.zip | |
[sanitizer] deadlock detector: a) initial support for suppressions, b) be more robust in case we failed to extract a stack trace for one of the locks
llvm-svn: 204225
6 files changed, 24 insertions, 7 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cc b/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cc index 5f3d2cee8ce..87ccf7fca22 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cc @@ -20,8 +20,8 @@ namespace __sanitizer { static const char *const kTypeStrings[SuppressionTypeCount] = { - "none", "race", "mutex", "thread", "signal", "leak", "called_from_lib" -}; + "none", "race", "mutex", "thread", + "signal", "leak", "called_from_lib", "deadlock"}; bool TemplateMatch(char *templ, const char *str) { if (str == 0 || str[0] == 0) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.h b/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.h index 92cb09365b5..772b9aab5ba 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.h @@ -26,6 +26,7 @@ enum SuppressionType { SuppressionSignal, SuppressionLeak, SuppressionLib, + SuppressionDeadlock, SuppressionTypeCount }; diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc index ea8741d4f01..93fc8a35dc8 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc @@ -67,8 +67,10 @@ TEST(Suppressions, TypeStrings) { CHECK(!internal_strcmp(SuppressionTypeString(SuppressionLeak), "leak")); CHECK(!internal_strcmp(SuppressionTypeString(SuppressionLib), "called_from_lib")); + CHECK( + !internal_strcmp(SuppressionTypeString(SuppressionDeadlock), "deadlock")); // Ensure this test is up-to-date when suppression types are added. - CHECK_EQ(SuppressionTypeCount, 7); + CHECK_EQ(SuppressionTypeCount, 8); } class SuppressionContextTest : public ::testing::Test { diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc index 8398e4b4522..ab083ab2940 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc @@ -428,17 +428,25 @@ void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r) { for (int i = 0; i < r->n; i++) rep.AddMutex(r->loop[i].mtx_ctx0); StackTrace stacks[2 * DDReport::kMaxLoopSize]; + uptr dummy_pc = 0x42; for (int i = 0; i < r->n; i++) { uptr size; for (int j = 0; j < 2; j++) { u32 stk = r->loop[i].stk[j]; - if (!stk) continue; - const uptr *trace = StackDepotGet(stk, &size); - stacks[i].Init(const_cast<uptr *>(trace), size); + if (stk) { + const uptr *trace = StackDepotGet(stk, &size); + stacks[i].Init(const_cast<uptr *>(trace), size); + } else { + // Sometimes we fail to extract the stack trace (FIXME: investigate), + // but we should still produce some stack trace in the report. + stacks[i].Init(&dummy_pc, 1); + } rep.AddStack(&stacks[i]); } } - OutputReport(ctx, rep); + // FIXME: use all stacks for suppressions, not just the second stack of the + // first edge. + OutputReport(ctx, rep, rep.GetReport()->stacks[1]); #endif // TSAN_GO } diff --git a/compiler-rt/lib/tsan/rtl/tsan_suppressions.cc b/compiler-rt/lib/tsan/rtl/tsan_suppressions.cc index 4b0ac04c48a..608b7af5f20 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_suppressions.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_suppressions.cc @@ -107,6 +107,8 @@ SuppressionType conv(ReportType typ) { return SuppressionSignal; else if (typ == ReportTypeErrnoInSignal) return SuppressionNone; + else if (typ == ReportTypeDeadlock) + return SuppressionDeadlock; Printf("ThreadSanitizer: unknown report type %d\n", typ), Die(); } diff --git a/compiler-rt/test/tsan/mutex_cycle2.c b/compiler-rt/test/tsan/mutex_cycle2.c index 32bb067567f..bb4c1b04938 100644 --- a/compiler-rt/test/tsan/mutex_cycle2.c +++ b/compiler-rt/test/tsan/mutex_cycle2.c @@ -1,5 +1,9 @@ // RUN: %clangxx_tsan %s -o %t // RUN: TSAN_OPTIONS=detect_deadlocks=1 not %t 2>&1 | FileCheck %s +// RUN: echo "deadlock:main" > sup +// RUN: TSAN_OPTIONS="detect_deadlocks=1 suppressions=sup" %t +// RUN: echo "deadlock:zzzz" > sup +// RUN: TSAN_OPTIONS="detect_deadlocks=1 suppressions=sup" not %t 2>&1 | FileCheck %s #include <pthread.h> int main() { |

