[compiler-rt] r202843 - tsan: add dynamic library target for standalone deadlock detector

Dmitry Vyukov dvyukov at google.com
Tue Mar 4 04:52:20 PST 2014


Author: dvyukov
Date: Tue Mar  4 06:52:20 2014
New Revision: 202843

URL: http://llvm.org/viewvc/llvm-project?rev=202843&view=rev
Log:
tsan: add dynamic library target for standalone deadlock detector
it's LD_PRELOAD-able



Added:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc
Modified:
    compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
    compiler-rt/trunk/lib/tsan/dd/CMakeLists.txt
    compiler-rt/trunk/lib/tsan/dd/dd_interceptors.cc
    compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc
    compiler-rt/trunk/lib/tsan/dd/dd_rtl.h

Modified: compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt?rev=202843&r1=202842&r2=202843&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt Tue Mar  4 06:52:20 2014
@@ -6,6 +6,7 @@ set(SANITIZER_SOURCES
   sanitizer_common.cc
   sanitizer_coverage.cc
   sanitizer_deadlock_detector1.cc
+  sanitizer_deadlock_detector2.cc
   sanitizer_flags.cc
   sanitizer_libc.cc
   sanitizer_libignore.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=202843&r1=202842&r2=202843&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  4 06:52:20 2014
@@ -17,6 +17,8 @@
 #include "sanitizer_placement_new.h"
 #include "sanitizer_mutex.h"
 
+#if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1
+
 namespace __sanitizer {
 
 typedef TwoLevelBitVector<> DDBV;  // DeadlockDetector's bit vector.
@@ -142,3 +144,4 @@ void DDetectorImpl::MutexDestroy(DDPhysi
 }
 
 }  // namespace __sanitizer
+#endif  // #if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1

Added: 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=202843&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector2.cc Tue Mar  4 06:52:20 2014
@@ -0,0 +1,139 @@
+//===-- sanitizer_deadlock_detector1.cc -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Deadlock detector implementation based on NxN adjacency bit matrix.
+//
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_deadlock_detector_interface.h"
+#include "sanitizer_allocator_internal.h"
+#include "sanitizer_placement_new.h"
+//#include "sanitizer_mutex.h"
+
+#if SANITIZER_DEADLOCK_DETECTOR_VERSION == 2
+
+namespace __sanitizer {
+
+struct DDPhysicalThread {
+  DDReport rep;
+};
+
+struct DDLogicalThread {
+  u64 ctx;
+};
+
+struct DDetectorImpl : public DDetector {
+  DDetectorImpl();
+
+  virtual DDPhysicalThread* CreatePhysicalThread();
+  virtual void DestroyPhysicalThread(DDPhysicalThread *pt);
+
+  virtual DDLogicalThread* CreateLogicalThread(u64 ctx);
+  virtual void DestroyLogicalThread(DDLogicalThread *lt);
+
+  virtual void MutexInit(DDMutex *m, u32 stk, u64 ctx);
+  virtual DDReport *MutexLock(DDPhysicalThread *pt, DDLogicalThread *lt,
+      DDMutex *m, bool writelock, bool trylock);
+  virtual DDReport *MutexUnlock(DDPhysicalThread *pt, DDLogicalThread *lt,
+      DDMutex *m, bool writelock);
+  virtual void MutexDestroy(DDPhysicalThread *pt, DDLogicalThread *lt,
+      DDMutex *m);
+};
+
+DDetector *DDetector::Create() {
+  void *mem = MmapOrDie(sizeof(DDetectorImpl), "deadlock detector");
+  return new(mem) DDetectorImpl();
+}
+
+DDetectorImpl::DDetectorImpl() {
+}
+
+DDPhysicalThread* DDetectorImpl::CreatePhysicalThread() {
+  void *mem = InternalAlloc(sizeof(DDPhysicalThread));
+  DDPhysicalThread *pt = new(mem) DDPhysicalThread();
+  return pt;
+}
+
+void DDetectorImpl::DestroyPhysicalThread(DDPhysicalThread *pt) {
+  pt->~DDPhysicalThread();
+  InternalFree(pt);
+}
+
+DDLogicalThread* DDetectorImpl::CreateLogicalThread(u64 ctx) {
+  void *mem = InternalAlloc(sizeof(
+  DDLogicalThread));
+  DDLogicalThread *lt = new(mem) DDLogicalThread();
+  lt->ctx = ctx;
+  return lt;
+}
+
+void DDetectorImpl::DestroyLogicalThread(DDLogicalThread *lt) {
+  lt->~DDLogicalThread();
+  InternalFree(lt);
+}
+
+void DDetectorImpl::MutexInit(DDMutex *m, u32 stk, u64 ctx) {
+  m->id = 0;
+  m->stk = stk;
+  m->ctx = ctx;
+}
+
+DDReport *DDetectorImpl::MutexLock(DDPhysicalThread *pt, DDLogicalThread *lt,
+    DDMutex *m, bool writelock, bool trylock) {
+    /*
+  if (dd.onFirstLock(&lt->dd, m->id))
+    return 0;
+  SpinMutexLock lk(&mtx);
+  MutexEnsureID(lt, m);
+  CHECK(!dd.isHeld(&lt->dd, m->id));
+  // Printf("T%d MutexLock:   %zx\n", thr->tid, s->deadlock_detector_id);
+  bool has_deadlock = trylock
+      ? dd.onTryLock(&lt->dd, m->id)
+       : dd.onLock(&lt->dd, m->id);
+  DDReport *rep = 0;
+  if (has_deadlock) {
+    uptr path[10];
+    uptr len = dd.findPathToHeldLock(&lt->dd, m->id,
+                                          path, ARRAY_SIZE(path));
+    CHECK_GT(len, 0U);  // Hm.. cycle of 10 locks? I'd like to see that.
+    rep = &lt->rep;
+    rep->n = len;
+    for (uptr i = 0; i < len; i++) {
+      DDMutex *m0 = (DDMutex*)dd.getData(path[i]);
+      DDMutex *m1 = (DDMutex*)dd.getData(path[i < len - 1 ? i + 1 : 0]);
+      rep->loop[i].thr_ctx = 0;  // don't know
+      rep->loop[i].mtx_ctx0 = m0->ctx;
+      rep->loop[i].mtx_ctx1 = m1->ctx;
+      rep->loop[i].stk = m0->stk;
+    }
+  }
+  return rep;
+  */
+  return 0;
+}
+
+DDReport *DDetectorImpl::MutexUnlock(DDPhysicalThread *pt, DDLogicalThread *lt,
+    DDMutex *m, bool writelock) {
+  //dd.onUnlock(&lt->dd, m->id);
+  return 0;
+}
+
+void DDetectorImpl::MutexDestroy(DDPhysicalThread *pt, DDLogicalThread *lt,
+    DDMutex *m) {
+    /*
+  if (!m->id) return;
+  SpinMutexLock lk(&mtx);
+  if (dd.nodeBelongsToCurrentEpoch(m->id))
+    dd.removeNode(m->id);
+  m->id = 0;
+  */
+}
+
+}  // namespace __sanitizer
+#endif  // #if SANITIZER_DEADLOCK_DETECTOR_VERSION == 2

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=202843&r1=202842&r2=202843&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  4 06:52:20 2014
@@ -16,6 +16,8 @@
 #ifndef SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H
 #define SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H
 
+#define SANITIZER_DEADLOCK_DETECTOR_VERSION 1
+
 #include "sanitizer_internal_defs.h"
 
 namespace __sanitizer {

Modified: compiler-rt/trunk/lib/tsan/dd/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/dd/CMakeLists.txt?rev=202843&r1=202842&r2=202843&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/dd/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/tsan/dd/CMakeLists.txt Tue Mar  4 06:52:20 2014
@@ -11,6 +11,8 @@ else()
   set(DD_COMMON_DEFINITIONS DEBUG=1)
 endif()
 
+set(DD_DYNAMIC_DEFINITIONS DYNAMIC=1)
+
 set(DD_SOURCES
   dd_rtl.cc
   dd_interceptors.cc
@@ -22,7 +24,7 @@ set(DD_HEADERS
 
 add_custom_target(dd)
 # Deadlock detector is currently supported on 64-bit Linux only.
-if(CAN_TARGET_x86_64 AND UNIX AND NOT APPLE)
+if(CAN_TARGET_x86_64 AND UNIX AND NOT APPLE AND NOT ANDROID)
   set(arch "x86_64")
   add_compiler_rt_static_runtime(clang_rt.dd-${arch} ${arch}
     SOURCES ${DD_SOURCES}
@@ -31,6 +33,23 @@ if(CAN_TARGET_x86_64 AND UNIX AND NOT AP
             $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
     CFLAGS ${DD_CFLAGS}
     DEFS ${DD_COMMON_DEFINITIONS})
+
+  add_library(RTDD OBJECT ${DD_SOURCES})
+  set_target_compile_flags(RTDD ${DD_CFLAGS})
+  set_property(TARGET RTDD APPEND PROPERTY
+    COMPILE_DEFINITIONS ${DD_COMMON_DEFINITIONS})
+  set_property(TARGET RTDD APPEND PROPERTY
+    COMPILE_DEFINITIONS ${DD_DYNAMIC_DEFINITIONS})
+
+  add_library(clang_rt.dyndd-${arch} SHARED
+    $<TARGET_OBJECTS:RTDD>
+    $<TARGET_OBJECTS:RTInterception.${arch}>
+    $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
+    $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)
+#  set_target_compile_flags(clang_rt.dd-${arch} ${DD_CFLAGS})
+#  set_property(TARGET clang_rt.dd-${arch} APPEND PROPERTY
+#    COMPILE_DEFINITIONS ${DD_COMMON_DEFINITIONS})
+  target_link_libraries(clang_rt.dyndd-${arch} pthread dl)
 endif()
 
 add_dependencies(compiler-rt dd)

Modified: compiler-rt/trunk/lib/tsan/dd/dd_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/dd/dd_interceptors.cc?rev=202843&r1=202842&r2=202843&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/dd/dd_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/dd/dd_interceptors.cc Tue Mar  4 06:52:20 2014
@@ -66,3 +66,13 @@ void InitializeInterceptors() {
 }
 
 }  // namespace __dsan
+
+#if DYNAMIC
+static void __local_dsan_init() __attribute__((constructor));
+void __local_dsan_init() {
+  __dsan::Initialize();
+}
+#else
+__attribute__((section(".preinit_array"), used))
+void (*__local_dsan_preinit)(void) = __dsan::Initialize;
+#endif

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=202843&r1=202842&r2=202843&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/dd/dd_rtl.cc Tue Mar  4 06:52:20 2014
@@ -100,6 +100,3 @@ void MutexDestroy(Thread *thr, uptr m) {
 }
 
 }  // namespace __dsan
-
-__attribute__((section(".preinit_array"), used))
-void (*__local_dsan_preinit)(void) = __dsan::Initialize;

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=202843&r1=202842&r2=202843&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/dd/dd_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/dd/dd_rtl.h Tue Mar  4 06:52:20 2014
@@ -36,6 +36,7 @@ struct Context {
   MutexHashMap mutex_map;
 };
 
+void Initialize();
 void InitializeInterceptors();
 
 void ThreadInit(Thread *thr);





More information about the llvm-commits mailing list