[compiler-rt] r177647 - tsan: better reporting of thread leaks
Dmitry Vyukov
dvyukov at google.com
Thu Mar 21 09:55:18 PDT 2013
Author: dvyukov
Date: Thu Mar 21 11:55:17 2013
New Revision: 177647
URL: http://llvm.org/viewvc/llvm-project?rev=177647&view=rev
Log:
tsan: better reporting of thread leaks
1. do not report running threads as leaks
2. aggregate leaked threads by creation stack
Added:
compiler-rt/trunk/lib/tsan/lit_tests/thread_leak4.c
compiler-rt/trunk/lib/tsan/lit_tests/thread_leak5.c
Modified:
compiler-rt/trunk/lib/tsan/lit_tests/thread_leak3.c
compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
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_rtl_thread.cc
Modified: compiler-rt/trunk/lib/tsan/lit_tests/thread_leak3.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/thread_leak3.c?rev=177647&r1=177646&r2=177647&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/lit_tests/thread_leak3.c (original)
+++ compiler-rt/trunk/lib/tsan/lit_tests/thread_leak3.c Thu Mar 21 11:55:17 2013
@@ -1,5 +1,6 @@
// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
#include <pthread.h>
+#include <unistd.h>
void *Thread(void *x) {
return 0;
@@ -8,6 +9,7 @@ void *Thread(void *x) {
int main() {
pthread_t t;
pthread_create(&t, 0, Thread, 0);
+ sleep(1);
return 0;
}
Added: compiler-rt/trunk/lib/tsan/lit_tests/thread_leak4.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/thread_leak4.c?rev=177647&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/lit_tests/thread_leak4.c (added)
+++ compiler-rt/trunk/lib/tsan/lit_tests/thread_leak4.c Thu Mar 21 11:55:17 2013
@@ -0,0 +1,16 @@
+// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <unistd.h>
+
+void *Thread(void *x) {
+ sleep(10);
+ return 0;
+}
+
+int main() {
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ return 0;
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer: thread leak
Added: compiler-rt/trunk/lib/tsan/lit_tests/thread_leak5.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/thread_leak5.c?rev=177647&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/lit_tests/thread_leak5.c (added)
+++ compiler-rt/trunk/lib/tsan/lit_tests/thread_leak5.c Thu Mar 21 11:55:17 2013
@@ -0,0 +1,19 @@
+// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <unistd.h>
+
+void *Thread(void *x) {
+ return 0;
+}
+
+int main() {
+ for (int i = 0; i < 5; i++) {
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ }
+ sleep(1);
+ return 0;
+}
+
+// CHECK: WARNING: ThreadSanitizer: thread leak
+// CHECK: And 4 more similar thread leaks
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=177647&r1=177646&r2=177647&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Thu Mar 21 11:55:17 2013
@@ -22,7 +22,8 @@ ReportDesc::ReportDesc()
, locs(MBlockReportLoc)
, mutexes(MBlockReportMutex)
, threads(MBlockReportThread)
- , sleep() {
+ , sleep()
+ , count() {
}
ReportMop::ReportMop()
@@ -201,6 +202,9 @@ void PrintReport(const ReportDesc *rep)
for (uptr i = 0; i < rep->threads.Size(); i++)
PrintThread(rep->threads[i]);
+ if (rep->typ == ReportTypeThreadLeak && rep->count > 1)
+ Printf(" And %d more similar thread leaks.\n\n", rep->count - 1);
+
if (ReportStack *ent = SkipTsanInternalFrames(ChooseSummaryStack(rep)))
ReportErrorSummary(rep_typ_str, ent->file, ent->line, ent->func);
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.h?rev=177647&r1=177646&r2=177647&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.h Thu Mar 21 11:55:17 2013
@@ -102,6 +102,7 @@ class ReportDesc {
Vector<ReportMutex*> mutexes;
Vector<ReportThread*> threads;
ReportStack *sleep;
+ int count;
ReportDesc();
~ReportDesc();
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=177647&r1=177646&r2=177647&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Thu Mar 21 11:55:17 2013
@@ -554,6 +554,7 @@ class ScopedReport {
void AddMutex(const SyncVar *s);
void AddLocation(uptr addr, uptr size);
void AddSleep(u32 stack_id);
+ void SetCount(int count);
const ReportDesc *GetReport() const;
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=177647&r1=177646&r2=177647&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc Thu Mar 21 11:55:17 2013
@@ -365,6 +365,10 @@ void ScopedReport::AddSleep(u32 stack_id
}
#endif
+void ScopedReport::SetCount(int count) {
+ rep_->count = count;
+}
+
const ReportDesc *ScopedReport::GetReport() const {
return rep_;
}
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc?rev=177647&r1=177646&r2=177647&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc Thu Mar 21 11:55:17 2013
@@ -143,26 +143,44 @@ void ThreadContext::OnFinished() {
thr = 0;
}
-static void MaybeReportThreadLeak(ThreadContextBase *tctx_base, void *unused) {
+#ifndef TSAN_GO
+struct ThreadLeak {
+ ThreadContext *tctx;
+ int count;
+};
+
+static void MaybeReportThreadLeak(ThreadContextBase *tctx_base, void *arg) {
+ Vector<ThreadLeak> &leaks = *(Vector<ThreadLeak>*)arg;
ThreadContext *tctx = static_cast<ThreadContext*>(tctx_base);
- if (tctx->detached)
- return;
- if (tctx->status != ThreadStatusCreated
- && tctx->status != ThreadStatusRunning
- && tctx->status != ThreadStatusFinished)
+ if (tctx->detached || tctx->status != ThreadStatusFinished)
return;
- ScopedReport rep(ReportTypeThreadLeak);
- rep.AddThread(tctx);
- OutputReport(CTX(), rep);
+ for (uptr i = 0; i < leaks.Size(); i++) {
+ if (leaks[i].tctx->creation_stack_id == tctx->creation_stack_id) {
+ leaks[i].count++;
+ return;
+ }
+ }
+ ThreadLeak leak = {tctx, 1};
+ leaks.PushBack(leak);
}
+#endif
void ThreadFinalize(ThreadState *thr) {
CHECK_GT(thr->in_rtl, 0);
+#ifndef TSAN_GO
if (!flags()->report_thread_leaks)
return;
ThreadRegistryLock l(CTX()->thread_registry);
+ Vector<ThreadLeak> leaks(MBlockScopedBuf);
CTX()->thread_registry->RunCallbackForEachThreadLocked(
- MaybeReportThreadLeak, 0);
+ MaybeReportThreadLeak, &leaks);
+ for (uptr i = 0; i < leaks.Size(); i++) {
+ ScopedReport rep(ReportTypeThreadLeak);
+ rep.AddThread(leaks[i].tctx);
+ rep.SetCount(leaks[i].count);
+ OutputReport(CTX(), rep);
+ }
+#endif
}
int ThreadCount(ThreadState *thr) {
More information about the llvm-commits
mailing list