[compiler-rt] r204150 - tsan: deadlock detector: add deadlock detector flags

Kostya Serebryany kcc at google.com
Wed Mar 19 01:16:13 PDT 2014


the new flag (second_deadlock_stack) has to be in common flags because
eventually we want the deadlock detector bundled with other sanitizers (at
least, asan).
Also, i'd make it an int rather than bool, so that we can set the maximal
length of the collected stack trace.
Then also add lit tests for this flag, please.
Finally, please update docs at
https://code.google.com/p/thread-sanitizer/wiki/DeadlockDetector


On Tue, Mar 18, 2014 at 5:13 PM, Dmitry Vyukov <dvyukov at google.com> wrote:

> Author: dvyukov
> Date: Tue Mar 18 08:13:47 2014
> New Revision: 204150
>
> URL: http://llvm.org/viewvc/llvm-project?rev=204150&view=rev
> Log:
> tsan: deadlock detector: add deadlock detector flags
> the first flags is to enable printing of the second stack per edge
>
>
> Modified:
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc
>
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
>     compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc
>     compiler-rt/trunk/lib/tsan/dd/dd_rtl.h
>     compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
>     compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h
>     compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc?rev=204150&r1=204149&r2=204150&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
> Tue Mar 18 08:13:47 2014
> @@ -56,7 +56,8 @@ struct DD : public DDetector {
>    void MutexEnsureID(DDLogicalThread *lt, DDMutex *m);
>  };
>
> -DDetector *DDetector::Create() {
> +DDetector *DDetector::Create(const DDFlags *flags) {
> +  (void)flags;
>    void *mem = MmapOrDie(sizeof(DD), "deadlock detector");
>    return new(mem) DD();
>  }
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc?rev=204150&r1=204149&r2=204150&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc
> Tue Mar 18 08:13:47 2014
> @@ -82,7 +82,7 @@ struct Mutex {
>  };
>
>  struct DD : public DDetector {
> -  explicit DD();
> +  explicit DD(const DDFlags *flags);
>
>    DDPhysicalThread* CreatePhysicalThread();
>    void DestroyPhysicalThread(DDPhysicalThread *pt);
> @@ -105,21 +105,24 @@ struct DD : public DDetector {
>    Mutex *getMutex(u32 id);
>    u32 getMutexId(Mutex *m);
>
> +  DDFlags flags;
> +
> +  Mutex* mutex[kL1Size];
> +
>    SpinMutex mtx;
>    InternalMmapVector<u32> free_id;
> -
>    int id_gen;
> -
> -  Mutex* mutex[kL1Size];
>  };
>
> -DDetector *DDetector::Create() {
> +DDetector *DDetector::Create(const DDFlags *flags) {
> +  (void)flags;
>    void *mem = MmapOrDie(sizeof(DD), "deadlock detector");
> -  return new(mem) DD();
> +  return new(mem) DD(flags);
>  }
>
> -DD::DD()
> -    : free_id(1024) {
> +DD::DD(const DDFlags *flags)
> +    : flags(*flags)
> +    , free_id(1024) {
>    id_gen = 0;
>  }
>
> @@ -210,7 +213,8 @@ void DD::MutexBeforeLock(DDCallback *cb,
>
>    ThreadMutex *tm = &lt->locked[lt->nlocked++];
>    tm->id = m->id;
> -  tm->stk = cb->Unwind();
> +  if (flags.second_deadlock_stack)
> +    tm->stk = cb->Unwind();
>    if (lt->nlocked == 1) {
>      VPrintf(3, "#%llu: DD::MutexBeforeLock first mutex\n",
>          cb->lt->ctx);
> @@ -296,7 +300,8 @@ void DD::MutexAfterLock(DDCallback *cb,
>      m->id = allocateId(cb);
>    ThreadMutex *tm = &lt->locked[lt->nlocked++];
>    tm->id = m->id;
> -  tm->stk = cb->Unwind();
> +  if (flags.second_deadlock_stack)
> +    tm->stk = cb->Unwind();
>  }
>
>  void DD::MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {
> @@ -407,7 +412,7 @@ void DD::Report(DDPhysicalThread *pt, DD
>      rep->loop[i].thr_ctx = link->tid;
>      rep->loop[i].mtx_ctx0 = link0->id;
>      rep->loop[i].mtx_ctx1 = link->id;
> -    rep->loop[i].stk[0] = link->stk0;
> +    rep->loop[i].stk[0] = flags.second_deadlock_stack ? link->stk0 : 0;
>      rep->loop[i].stk[1] = link->stk1;
>    }
>    pt->report_pending = true;
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h?rev=204150&r1=204149&r2=204150&view=diff
>
> ==============================================================================
> ---
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
> (original)
> +++
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
> Tue Mar 18 08:13:47 2014
> @@ -46,6 +46,10 @@ struct DDMutex {
>    u64  ctx;
>  };
>
> +struct DDFlags {
> +  bool second_deadlock_stack;
> +};
> +
>  struct DDReport {
>    enum { kMaxLoopSize = 8 };
>    int n;  // number of entries in loop
> @@ -65,7 +69,7 @@ struct DDCallback {
>  };
>
>  struct DDetector {
> -  static DDetector *Create();
> +  static DDetector *Create(const DDFlags *flags);
>
>    virtual DDPhysicalThread* CreatePhysicalThread() { return 0; }
>    virtual void DestroyPhysicalThread(DDPhysicalThread *pt) {}
>
> Modified: compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc?rev=204150&r1=204149&r2=204150&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc (original)
> +++ compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc Tue Mar 18 08:13:47 2014
> @@ -45,9 +45,11 @@ static void ReportDeadlock(Thread *thr,
>      Printf("Thread %d locks mutex %llu while holding mutex %llu:\n",
>        rep->loop[i].thr_ctx, rep->loop[i].mtx_ctx1, rep->loop[i].mtx_ctx0);
>      PrintStackTrace(thr, rep->loop[i].stk[1]);
> -    Printf("Mutex %llu was acquired here:\n",
> -      rep->loop[i].mtx_ctx0);
> -    PrintStackTrace(thr, rep->loop[i].stk[0]);
> +    if (rep->loop[i].stk[0]) {
> +      Printf("Mutex %llu was acquired here:\n",
> +        rep->loop[i].mtx_ctx0);
> +      PrintStackTrace(thr, rep->loop[i].stk[0]);
> +    }
>    }
>    Printf("==============================\n");
>    Die();
> @@ -63,15 +65,32 @@ u32 Callback::Unwind() {
>    return CurrentStackTrace(thr, 3);
>  }
>
> +void InitializeFlags(Flags *f, const char *env) {
> +  internal_memset(f, 0, sizeof(*f));
> +
> +  // Default values.
> +  f->second_deadlock_stack = false;
> +
> +  SetCommonFlagsDefaults(f);
> +  // Override some common flags defaults.
> +  f->allow_addr2line = true;
> +
> +  // Override from command line.
> +  ParseFlag(env, &f->second_deadlock_stack, "second_deadlock_stack");
> +  ParseCommonFlagsFromString(f, env);
> +
> +  // Copy back to common flags.
> +  *common_flags() = *f;
> +}
> +
>  void Initialize() {
>    static u64 ctx_mem[sizeof(Context) / sizeof(u64) + 1];
>    ctx = new(ctx_mem) Context();
>
>    InitializeInterceptors();
> -  ParseCommonFlagsFromString(flags(), GetEnv("DSAN_OPTIONS"));
> -  //common_flags()->allow_addr2line = true;
> +  InitializeFlags(flags(), GetEnv("DSAN_OPTIONS"));
>    common_flags()->symbolize = true;
> -  ctx->dd = DDetector::Create();
> +  ctx->dd = DDetector::Create(flags());
>  }
>
>  void ThreadInit(Thread *thr) {
>
> Modified: compiler-rt/trunk/lib/tsan/dd/dd_rtl.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/dd/dd_rtl.h?rev=204150&r1=204149&r2=204150&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/dd/dd_rtl.h (original)
> +++ compiler-rt/trunk/lib/tsan/dd/dd_rtl.h Tue Mar 18 08:13:47 2014
> @@ -18,6 +18,9 @@
>
>  namespace __dsan {
>
> +struct Flags : CommonFlags, DDFlags {
> +};
> +
>  struct Mutex {
>    DDMutex dd;
>  };
> @@ -44,8 +47,9 @@ struct Context {
>    MutexHashMap mutex_map;
>  };
>
> -inline CommonFlags* flags() {
> -  return common_flags();
> +inline Flags* flags() {
> +  static Flags flags;
> +  return &flags;
>  }
>
>  void Initialize();
>
> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc?rev=204150&r1=204149&r2=204150&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc (original)
> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc Tue Mar 18 08:13:47 2014
> @@ -59,6 +59,9 @@ static void ParseFlags(Flags *f, const c
>    ParseFlag(env, &f->history_size, "history_size");
>    ParseFlag(env, &f->io_sync, "io_sync");
>    ParseFlag(env, &f->die_after_fork, "die_after_fork");
> +
> +  // DDFlags
> +  ParseFlag(env, &f->second_deadlock_stack, "second_deadlock_stack");
>  }
>
>  void InitializeFlags(Flags *f, const char *env) {
> @@ -91,6 +94,9 @@ void InitializeFlags(Flags *f, const cha
>    f->io_sync = 1;
>    f->die_after_fork = true;
>
> +  // DDFlags
> +  f->second_deadlock_stack = false;
> +
>    SetCommonFlagsDefaults(f);
>    // Override some common flags defaults.
>    f->allow_addr2line = true;
>
> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h?rev=204150&r1=204149&r2=204150&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h (original)
> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h Tue Mar 18 08:13:47 2014
> @@ -15,10 +15,11 @@
>  #define TSAN_FLAGS_H
>
>  #include "sanitizer_common/sanitizer_flags.h"
> +#include "sanitizer_common/sanitizer_deadlock_detector_interface.h"
>
>  namespace __tsan {
>
> -struct Flags : CommonFlags {
> +struct Flags : CommonFlags, DDFlags {
>    // Enable dynamic annotations, otherwise they are no-ops.
>    bool enable_annotations;
>    // Supress a race report if we've already output another race report
>
> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=204150&r1=204149&r2=204150&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Tue Mar 18 08:13:47 2014
> @@ -251,7 +251,7 @@ void Initialize(ThreadState *thr) {
>  #endif
>    internal_start_thread(&BackgroundThread, 0);
>    if (flags()->detect_deadlocks)
> -    ctx->dd = DDetector::Create();
> +    ctx->dd = DDetector::Create(flags());
>
>    if (ctx->flags.verbosity)
>      Printf("***** Running under ThreadSanitizer v2 (pid %d) *****\n",
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140319/c0553690/attachment.html>


More information about the llvm-commits mailing list