[compiler-rt] r177647 - tsan: better reporting of thread leaks

David Blaikie dblaikie at gmail.com
Thu Mar 21 13:16:09 PDT 2013


On Thu, Mar 21, 2013 at 9:55 AM, Dmitry Vyukov <dvyukov at google.com> wrote:
> 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

This seems to be failing:

Failing Tests (1):
    ThreadSanitizer :: 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) {
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list