<div dir="ltr">the new flag (<span style="font-family:arial,sans-serif;font-size:13px">second_deadlock_stack</span>) has to be in common flags because eventually we want the deadlock detector bundled with other sanitizers (at least, asan). <div>
Also, i'd make it an int rather than bool, so that we can set the maximal length of the collected stack trace.</div><div>Then also add lit tests for this flag, please.</div><div>Finally, please update docs at <a href="https://code.google.com/p/thread-sanitizer/wiki/DeadlockDetector">https://code.google.com/p/thread-sanitizer/wiki/DeadlockDetector</a></div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Mar 18, 2014 at 5:13 PM, Dmitry Vyukov <span dir="ltr"><<a href="mailto:dvyukov@google.com" target="_blank">dvyukov@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dvyukov<br>
Date: Tue Mar 18 08:13:47 2014<br>
New Revision: 204150<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=204150&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=204150&view=rev</a><br>
Log:<br>
tsan: deadlock detector: add deadlock detector flags<br>
the first flags is to enable printing of the second stack per edge<br>
<br>
<br>
Modified:<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h<br>
    compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc<br>
    compiler-rt/trunk/lib/tsan/dd/dd_rtl.h<br>
    compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc<br>
    compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h<br>
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc?rev=204150&r1=204149&r2=204150&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc?rev=204150&r1=204149&r2=204150&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc Tue Mar 18 08:13:47 2014<br>
@@ -56,7 +56,8 @@ struct DD : public DDetector {<br>
   void MutexEnsureID(DDLogicalThread *lt, DDMutex *m);<br>
 };<br>
<br>
-DDetector *DDetector::Create() {<br>
+DDetector *DDetector::Create(const DDFlags *flags) {<br>
+  (void)flags;<br>
   void *mem = MmapOrDie(sizeof(DD), "deadlock detector");<br>
   return new(mem) DD();<br>
 }<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc?rev=204150&r1=204149&r2=204150&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc?rev=204150&r1=204149&r2=204150&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc Tue Mar 18 08:13:47 2014<br>
@@ -82,7 +82,7 @@ struct Mutex {<br>
 };<br>
<br>
 struct DD : public DDetector {<br>
-  explicit DD();<br>
+  explicit DD(const DDFlags *flags);<br>
<br>
   DDPhysicalThread* CreatePhysicalThread();<br>
   void DestroyPhysicalThread(DDPhysicalThread *pt);<br>
@@ -105,21 +105,24 @@ struct DD : public DDetector {<br>
   Mutex *getMutex(u32 id);<br>
   u32 getMutexId(Mutex *m);<br>
<br>
+  DDFlags flags;<br>
+<br>
+  Mutex* mutex[kL1Size];<br>
+<br>
   SpinMutex mtx;<br>
   InternalMmapVector<u32> free_id;<br>
-<br>
   int id_gen;<br>
-<br>
-  Mutex* mutex[kL1Size];<br>
 };<br>
<br>
-DDetector *DDetector::Create() {<br>
+DDetector *DDetector::Create(const DDFlags *flags) {<br>
+  (void)flags;<br>
   void *mem = MmapOrDie(sizeof(DD), "deadlock detector");<br>
-  return new(mem) DD();<br>
+  return new(mem) DD(flags);<br>
 }<br>
<br>
-DD::DD()<br>
-    : free_id(1024) {<br>
+DD::DD(const DDFlags *flags)<br>
+    : flags(*flags)<br>
+    , free_id(1024) {<br>
   id_gen = 0;<br>
 }<br>
<br>
@@ -210,7 +213,8 @@ void DD::MutexBeforeLock(DDCallback *cb,<br>
<br>
   ThreadMutex *tm = &lt->locked[lt->nlocked++];<br>
   tm->id = m->id;<br>
-  tm->stk = cb->Unwind();<br>
+  if (flags.second_deadlock_stack)<br>
+    tm->stk = cb->Unwind();<br>
   if (lt->nlocked == 1) {<br>
     VPrintf(3, "#%llu: DD::MutexBeforeLock first mutex\n",<br>
         cb->lt->ctx);<br>
@@ -296,7 +300,8 @@ void DD::MutexAfterLock(DDCallback *cb,<br>
     m->id = allocateId(cb);<br>
   ThreadMutex *tm = &lt->locked[lt->nlocked++];<br>
   tm->id = m->id;<br>
-  tm->stk = cb->Unwind();<br>
+  if (flags.second_deadlock_stack)<br>
+    tm->stk = cb->Unwind();<br>
 }<br>
<br>
 void DD::MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {<br>
@@ -407,7 +412,7 @@ void DD::Report(DDPhysicalThread *pt, DD<br>
     rep->loop[i].thr_ctx = link->tid;<br>
     rep->loop[i].mtx_ctx0 = link0->id;<br>
     rep->loop[i].mtx_ctx1 = link->id;<br>
-    rep->loop[i].stk[0] = link->stk0;<br>
+    rep->loop[i].stk[0] = flags.second_deadlock_stack ? link->stk0 : 0;<br>
     rep->loop[i].stk[1] = link->stk1;<br>
   }<br>
   pt->report_pending = true;<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h<br>
URL: <a href="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" target="_blank">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</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h Tue Mar 18 08:13:47 2014<br>
@@ -46,6 +46,10 @@ struct DDMutex {<br>
   u64  ctx;<br>
 };<br>
<br>
+struct DDFlags {<br>
+  bool second_deadlock_stack;<br>
+};<br>
+<br>
 struct DDReport {<br>
   enum { kMaxLoopSize = 8 };<br>
   int n;  // number of entries in loop<br>
@@ -65,7 +69,7 @@ struct DDCallback {<br>
 };<br>
<br>
 struct DDetector {<br>
-  static DDetector *Create();<br>
+  static DDetector *Create(const DDFlags *flags);<br>
<br>
   virtual DDPhysicalThread* CreatePhysicalThread() { return 0; }<br>
   virtual void DestroyPhysicalThread(DDPhysicalThread *pt) {}<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc?rev=204150&r1=204149&r2=204150&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc?rev=204150&r1=204149&r2=204150&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc Tue Mar 18 08:13:47 2014<br>
@@ -45,9 +45,11 @@ static void ReportDeadlock(Thread *thr,<br>
     Printf("Thread %d locks mutex %llu while holding mutex %llu:\n",<br>
       rep->loop[i].thr_ctx, rep->loop[i].mtx_ctx1, rep->loop[i].mtx_ctx0);<br>
     PrintStackTrace(thr, rep->loop[i].stk[1]);<br>
-    Printf("Mutex %llu was acquired here:\n",<br>
-      rep->loop[i].mtx_ctx0);<br>
-    PrintStackTrace(thr, rep->loop[i].stk[0]);<br>
+    if (rep->loop[i].stk[0]) {<br>
+      Printf("Mutex %llu was acquired here:\n",<br>
+        rep->loop[i].mtx_ctx0);<br>
+      PrintStackTrace(thr, rep->loop[i].stk[0]);<br>
+    }<br>
   }<br>
   Printf("==============================\n");<br>
   Die();<br>
@@ -63,15 +65,32 @@ u32 Callback::Unwind() {<br>
   return CurrentStackTrace(thr, 3);<br>
 }<br>
<br>
+void InitializeFlags(Flags *f, const char *env) {<br>
+  internal_memset(f, 0, sizeof(*f));<br>
+<br>
+  // Default values.<br>
+  f->second_deadlock_stack = false;<br>
+<br>
+  SetCommonFlagsDefaults(f);<br>
+  // Override some common flags defaults.<br>
+  f->allow_addr2line = true;<br>
+<br>
+  // Override from command line.<br>
+  ParseFlag(env, &f->second_deadlock_stack, "second_deadlock_stack");<br>
+  ParseCommonFlagsFromString(f, env);<br>
+<br>
+  // Copy back to common flags.<br>
+  *common_flags() = *f;<br>
+}<br>
+<br>
 void Initialize() {<br>
   static u64 ctx_mem[sizeof(Context) / sizeof(u64) + 1];<br>
   ctx = new(ctx_mem) Context();<br>
<br>
   InitializeInterceptors();<br>
-  ParseCommonFlagsFromString(flags(), GetEnv("DSAN_OPTIONS"));<br>
-  //common_flags()->allow_addr2line = true;<br>
+  InitializeFlags(flags(), GetEnv("DSAN_OPTIONS"));<br>
   common_flags()->symbolize = true;<br>
-  ctx->dd = DDetector::Create();<br>
+  ctx->dd = DDetector::Create(flags());<br>
 }<br>
<br>
 void ThreadInit(Thread *thr) {<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/dd/dd_rtl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/dd/dd_rtl.h?rev=204150&r1=204149&r2=204150&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/dd/dd_rtl.h?rev=204150&r1=204149&r2=204150&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/dd/dd_rtl.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/dd/dd_rtl.h Tue Mar 18 08:13:47 2014<br>
@@ -18,6 +18,9 @@<br>
<br>
 namespace __dsan {<br>
<br>
+struct Flags : CommonFlags, DDFlags {<br>
+};<br>
+<br>
 struct Mutex {<br>
   DDMutex dd;<br>
 };<br>
@@ -44,8 +47,9 @@ struct Context {<br>
   MutexHashMap mutex_map;<br>
 };<br>
<br>
-inline CommonFlags* flags() {<br>
-  return common_flags();<br>
+inline Flags* flags() {<br>
+  static Flags flags;<br>
+  return &flags;<br>
 }<br>
<br>
 void Initialize();<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc?rev=204150&r1=204149&r2=204150&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc?rev=204150&r1=204149&r2=204150&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc Tue Mar 18 08:13:47 2014<br>
@@ -59,6 +59,9 @@ static void ParseFlags(Flags *f, const c<br>
   ParseFlag(env, &f->history_size, "history_size");<br>
   ParseFlag(env, &f->io_sync, "io_sync");<br>
   ParseFlag(env, &f->die_after_fork, "die_after_fork");<br>
+<br>
+  // DDFlags<br>
+  ParseFlag(env, &f->second_deadlock_stack, "second_deadlock_stack");<br>
 }<br>
<br>
 void InitializeFlags(Flags *f, const char *env) {<br>
@@ -91,6 +94,9 @@ void InitializeFlags(Flags *f, const cha<br>
   f->io_sync = 1;<br>
   f->die_after_fork = true;<br>
<br>
+  // DDFlags<br>
+  f->second_deadlock_stack = false;<br>
+<br>
   SetCommonFlagsDefaults(f);<br>
   // Override some common flags defaults.<br>
   f->allow_addr2line = true;<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h?rev=204150&r1=204149&r2=204150&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h?rev=204150&r1=204149&r2=204150&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h Tue Mar 18 08:13:47 2014<br>
@@ -15,10 +15,11 @@<br>
 #define TSAN_FLAGS_H<br>
<br>
 #include "sanitizer_common/sanitizer_flags.h"<br>
+#include "sanitizer_common/sanitizer_deadlock_detector_interface.h"<br>
<br>
 namespace __tsan {<br>
<br>
-struct Flags : CommonFlags {<br>
+struct Flags : CommonFlags, DDFlags {<br>
   // Enable dynamic annotations, otherwise they are no-ops.<br>
   bool enable_annotations;<br>
   // Supress a race report if we've already output another race report<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=204150&r1=204149&r2=204150&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=204150&r1=204149&r2=204150&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Tue Mar 18 08:13:47 2014<br>
@@ -251,7 +251,7 @@ void Initialize(ThreadState *thr) {<br>
 #endif<br>
   internal_start_thread(&BackgroundThread, 0);<br>
   if (flags()->detect_deadlocks)<br>
-    ctx->dd = DDetector::Create();<br>
+    ctx->dd = DDetector::Create(flags());<br>
<br>
   if (ctx->flags.verbosity)<br>
     Printf("***** Running under ThreadSanitizer v2 (pid %d) *****\n",<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>