[llvm-commits] [compiler-rt] r164487 - in /compiler-rt/trunk/lib/tsan/rtl: CMakeLists.txt Makefile.old tsan_interceptors.cc tsan_interceptors.h tsan_mman.cc tsan_mman.h tsan_new_delete.cc tsan_rtl.h

Alexey Samsonov samsonov at google.com
Mon Sep 24 06:19:47 PDT 2012


Author: samsonov
Date: Mon Sep 24 08:19:47 2012
New Revision: 164487

URL: http://llvm.org/viewvc/llvm-project?rev=164487&view=rev
Log:
[TSan] Provide replacements for operators new/delete instead of declaring extern C functions with weirdly mangled names (same strategy is used in ASan).

Added:
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_new_delete.cc
Modified:
    compiler-rt/trunk/lib/tsan/rtl/CMakeLists.txt
    compiler-rt/trunk/lib/tsan/rtl/Makefile.old
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h

Modified: compiler-rt/trunk/lib/tsan/rtl/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/CMakeLists.txt?rev=164487&r1=164486&r2=164487&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/tsan/rtl/CMakeLists.txt Mon Sep 24 08:19:47 2012
@@ -8,6 +8,7 @@
   tsan_md5.cc
   tsan_mman.cc
   tsan_mutex.cc
+  tsan_new_delete.cc
   tsan_printf.cc
   tsan_report.cc
   tsan_rtl.cc

Modified: compiler-rt/trunk/lib/tsan/rtl/Makefile.old
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/Makefile.old?rev=164487&r1=164486&r2=164487&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/Makefile.old (original)
+++ compiler-rt/trunk/lib/tsan/rtl/Makefile.old Mon Sep 24 08:19:47 2012
@@ -42,6 +42,8 @@
 
 %_linux.o: %_linux.cc Makefile.old $(LIBTSAN_HEADERS)
 	$(CXX) $(CXXFLAGS) $(INCLUDES) -c $<
+%_new_delete.o: %_new_delete.cc Makefile.old $(LIBTSAN_HEADERS)
+	$(CXX) $(CXXFLAGS) $(INCLUDES) -c $<
 %.o: %.cc Makefile.old $(LIBTSAN_HEADERS)
 	$(CXX) $(CXXFLAGS) $(INCLUDES) $(NO_SYSROOT) -c $<
 %.o: $(INTERCEPTION)/%.cc Makefile.old $(LIBTSAN_HEADERS)

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=164487&r1=164486&r2=164487&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Mon Sep 24 08:19:47 2012
@@ -1,4 +1,4 @@
-//===-- tsan_interceptors_linux.cc ----------------------------------------===//
+//===-- tsan_interceptors.cc ----------------------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -11,13 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "interception/interception.h"
 #include "sanitizer_common/sanitizer_atomic.h"
 #include "sanitizer_common/sanitizer_libc.h"
 #include "sanitizer_common/sanitizer_placement_new.h"
-#include "tsan_rtl.h"
+#include "tsan_interceptors.h"
 #include "tsan_interface.h"
 #include "tsan_platform.h"
+#include "tsan_rtl.h"
 #include "tsan_mman.h"
 
 using namespace __tsan;  // NOLINT
@@ -133,89 +133,27 @@
 
 static void process_pending_signals(ThreadState *thr);
 
-class ScopedInterceptor {
- public:
-  ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc)
-      : thr_(thr)
-      , in_rtl_(thr->in_rtl) {
-    if (thr_->in_rtl == 0) {
-      Initialize(thr);
-      FuncEntry(thr, pc);
-      thr_->in_rtl++;
-      DPrintf("#%d: intercept %s()\n", thr_->tid, fname);
-    } else {
-      thr_->in_rtl++;
-    }
-  }
-
-  ~ScopedInterceptor() {
-    thr_->in_rtl--;
-    if (thr_->in_rtl == 0) {
-      FuncExit(thr_);
-      process_pending_signals(thr_);
-    }
-    CHECK_EQ(in_rtl_, thr_->in_rtl);
+ScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname,
+                                     uptr pc)
+    : thr_(thr)
+    , in_rtl_(thr->in_rtl) {
+  if (thr_->in_rtl == 0) {
+    Initialize(thr);
+    FuncEntry(thr, pc);
+    thr_->in_rtl++;
+    DPrintf("#%d: intercept %s()\n", thr_->tid, fname);
+  } else {
+    thr_->in_rtl++;
   }
-
- private:
-  ThreadState *const thr_;
-  const int in_rtl_;
-};
-
-#define SCOPED_INTERCEPTOR_RAW(func, ...) \
-    ThreadState *thr = cur_thread(); \
-    StatInc(thr, StatInterceptor); \
-    StatInc(thr, StatInt_##func); \
-    ScopedInterceptor si(thr, #func, \
-        (__sanitizer::uptr)__builtin_return_address(0)); \
-    const uptr pc = (uptr)&func; \
-    (void)pc; \
-/**/
-
-#define SCOPED_TSAN_INTERCEPTOR(func, ...) \
-    SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
-    if (thr->in_rtl > 1) \
-      return REAL(func)(__VA_ARGS__); \
-/**/
-
-#define SCOPED_INTERCEPTOR_LIBC(func, ...) \
-    ThreadState *thr = cur_thread(); \
-    StatInc(thr, StatInterceptor); \
-    StatInc(thr, StatInt_##func); \
-    ScopedInterceptor si(thr, #func, callpc); \
-    const uptr pc = (uptr)&func; \
-    (void)pc; \
-    if (thr->in_rtl > 1) \
-      return REAL(func)(__VA_ARGS__); \
-/**/
-
-#define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__)
-#define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func)
-
-// May be overriden by front-end.
-extern "C" void WEAK __tsan_malloc_hook(void *ptr, uptr size) {
-  (void)ptr;
-  (void)size;
-}
-
-extern "C" void WEAK __tsan_free_hook(void *ptr) {
-  (void)ptr;
-}
-
-static void invoke_malloc_hook(void *ptr, uptr size) {
-  Context *ctx = CTX();
-  ThreadState *thr = cur_thread();
-  if (ctx == 0 || !ctx->initialized || thr->in_rtl)
-    return;
-  __tsan_malloc_hook(ptr, size);
 }
 
-static void invoke_free_hook(void *ptr) {
-  Context *ctx = CTX();
-  ThreadState *thr = cur_thread();
-  if (ctx == 0 || !ctx->initialized || thr->in_rtl)
-    return;
-  __tsan_free_hook(ptr);
+ScopedInterceptor::~ScopedInterceptor() {
+  thr_->in_rtl--;
+  if (thr_->in_rtl == 0) {
+    FuncExit(thr_);
+    process_pending_signals(thr_);
+  }
+  CHECK_EQ(in_rtl_, thr_->in_rtl);
 }
 
 TSAN_INTERCEPTOR(unsigned, sleep, unsigned sec) {
@@ -562,92 +500,6 @@
   return res;
 }
 
-#ifdef __LP64__
-
-// void *operator new(size_t)
-TSAN_INTERCEPTOR(void*, _Znwm, uptr sz) {
-  void *p = 0;
-  {
-    SCOPED_TSAN_INTERCEPTOR(_Znwm, sz);
-    p = user_alloc(thr, pc, sz);
-  }
-  invoke_malloc_hook(p, sz);
-  return p;
-}
-
-// void *operator new(size_t, nothrow_t)
-TSAN_INTERCEPTOR(void*, _ZnwmRKSt9nothrow_t, uptr sz) {
-  void *p = 0;
-  {
-    SCOPED_TSAN_INTERCEPTOR(_ZnwmRKSt9nothrow_t, sz);
-    p = user_alloc(thr, pc, sz);
-  }
-  invoke_malloc_hook(p, sz);
-  return p;
-}
-
-// void *operator new[](size_t)
-TSAN_INTERCEPTOR(void*, _Znam, uptr sz) {
-  void *p = 0;
-  {
-    SCOPED_TSAN_INTERCEPTOR(_Znam, sz);
-    p = user_alloc(thr, pc, sz);
-  }
-  invoke_malloc_hook(p, sz);
-  return p;
-}
-
-// void *operator new[](size_t, nothrow_t)
-TSAN_INTERCEPTOR(void*, _ZnamRKSt9nothrow_t, uptr sz) {
-  void *p = 0;
-  {
-    SCOPED_TSAN_INTERCEPTOR(_ZnamRKSt9nothrow_t, sz);
-    p = user_alloc(thr, pc, sz);
-  }
-  invoke_malloc_hook(p, sz);
-  return p;
-}
-
-#else
-#error "Not implemented"
-#endif
-
-// void operator delete(void*)
-TSAN_INTERCEPTOR(void, _ZdlPv, void *p) {
-  if (p == 0)
-    return;
-  invoke_free_hook(p);
-  SCOPED_TSAN_INTERCEPTOR(_ZdlPv, p);
-  user_free(thr, pc, p);
-}
-
-// void operator delete(void*, nothrow_t)
-TSAN_INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *p) {
-  if (p == 0)
-    return;
-  invoke_free_hook(p);
-  SCOPED_TSAN_INTERCEPTOR(_ZdlPvRKSt9nothrow_t, p);
-  user_free(thr, pc, p);
-}
-
-// void operator delete[](void*)
-TSAN_INTERCEPTOR(void, _ZdaPv, void *p) {
-  if (p == 0)
-    return;
-  invoke_free_hook(p);
-  SCOPED_TSAN_INTERCEPTOR(_ZdaPv, p);
-  user_free(thr, pc, p);
-}
-
-// void operator delete[](void*, nothrow_t)
-TSAN_INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *p) {
-  if (p == 0)
-    return;
-  invoke_free_hook(p);
-  SCOPED_TSAN_INTERCEPTOR(_ZdaPvRKSt9nothrow_t, p);
-  user_free(thr, pc, p);
-}
-
 TSAN_INTERCEPTOR(void*, memalign, uptr align, uptr sz) {
   SCOPED_TSAN_INTERCEPTOR(memalign, align, sz);
   return user_alloc(thr, pc, sz, align);
@@ -1447,7 +1299,7 @@
           sigactions[sig].sa_handler(sig);
         if (errno != 0) {
           ScopedInRtl in_rtl;
-          StackTrace stack;
+          __tsan::StackTrace stack;
           uptr pc = signal->sigaction ?
               (uptr)sigactions[sig].sa_sigaction :
               (uptr)sigactions[sig].sa_handler;
@@ -1491,14 +1343,7 @@
   TSAN_INTERCEPT(pvalloc);
   TSAN_INTERCEPT(posix_memalign);
 
-  TSAN_INTERCEPT(_Znwm);
-  TSAN_INTERCEPT(_ZnwmRKSt9nothrow_t);
-  TSAN_INTERCEPT(_Znam);
-  TSAN_INTERCEPT(_ZnamRKSt9nothrow_t);
-  TSAN_INTERCEPT(_ZdlPv);
-  TSAN_INTERCEPT(_ZdlPvRKSt9nothrow_t);
-  TSAN_INTERCEPT(_ZdaPv);
-  TSAN_INTERCEPT(_ZdaPvRKSt9nothrow_t);
+  ReplaceOperatorsNewAndDelete();
 
   TSAN_INTERCEPT(strlen);
   TSAN_INTERCEPT(memset);

Added: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.h?rev=164487&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.h (added)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.h Mon Sep 24 08:19:47 2012
@@ -0,0 +1,54 @@
+//===-- tsan_interceptors.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer (TSan), a race detector.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TSAN_INTERCEPTORS_H
+#define TSAN_INTERCEPTORS_H
+
+#include "interception/interception.h"
+#include "sanitizer_common/sanitizer_stacktrace.h"
+#include "tsan_rtl.h"
+
+namespace __tsan {
+
+class ScopedInterceptor {
+ public:
+  ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc);
+  ~ScopedInterceptor();
+ private:
+  ThreadState *const thr_;
+  const int in_rtl_;
+};
+
+#define SCOPED_INTERCEPTOR_RAW(func, ...) \
+    ThreadState *thr = cur_thread(); \
+    StatInc(thr, StatInterceptor); \
+    StatInc(thr, StatInt_##func); \
+    const uptr caller_pc = GET_CALLER_PC(); \
+    ScopedInterceptor si(thr, #func, caller_pc); \
+    /* Subtract one from pc as we need current instruction address */ \
+    const uptr pc = __sanitizer::StackTrace::GetCurrentPc() - 1; \
+    (void)pc; \
+/**/
+
+#define SCOPED_TSAN_INTERCEPTOR(func, ...) \
+    SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
+    if (thr->in_rtl > 1) \
+      return REAL(func)(__VA_ARGS__); \
+/**/
+
+#define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__)
+#define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func)
+
+}  // namespace __tsan
+
+#endif  // TSAN_INTERCEPTORS_H

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc?rev=164487&r1=164486&r2=164487&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc Mon Sep 24 08:19:47 2012
@@ -17,6 +17,16 @@
 #include "tsan_report.h"
 #include "tsan_flags.h"
 
+// May be overriden by front-end.
+extern "C" void WEAK __tsan_malloc_hook(void *ptr, uptr size) {
+  (void)ptr;
+  (void)size;
+}
+
+extern "C" void WEAK __tsan_free_hook(void *ptr) {
+  (void)ptr;
+}
+
 namespace __tsan {
 
 static char allocator_placeholder[sizeof(Allocator)] ALIGNED(64);
@@ -109,6 +119,22 @@
   return (MBlock*)allocator()->GetMetaData(p);
 }
 
+void invoke_malloc_hook(void *ptr, uptr size) {
+  Context *ctx = CTX();
+  ThreadState *thr = cur_thread();
+  if (ctx == 0 || !ctx->initialized || thr->in_rtl)
+    return;
+  __tsan_malloc_hook(ptr, size);
+}
+
+void invoke_free_hook(void *ptr) {
+  Context *ctx = CTX();
+  ThreadState *thr = cur_thread();
+  if (ctx == 0 || !ctx->initialized || thr->in_rtl)
+    return;
+  __tsan_free_hook(ptr);
+}
+
 void *internal_alloc(MBlockType typ, uptr sz) {
   ThreadState *thr = cur_thread();
   CHECK_GT(thr->in_rtl, 0);

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h?rev=164487&r1=164486&r2=164487&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h Mon Sep 24 08:19:47 2012
@@ -33,6 +33,10 @@
 // returns the descriptor of the block.
 MBlock *user_mblock(ThreadState *thr, void *p);
 
+// Invoking malloc/free hooks that may be installed by the user.
+void invoke_malloc_hook(void *ptr, uptr size);
+void invoke_free_hook(void *ptr);
+
 enum MBlockType {
   MBlockScopedBuf,
   MBlockString,

Added: compiler-rt/trunk/lib/tsan/rtl/tsan_new_delete.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_new_delete.cc?rev=164487&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_new_delete.cc (added)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_new_delete.cc Mon Sep 24 08:19:47 2012
@@ -0,0 +1,70 @@
+//===-- tsan_new_delete.cc ------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer (TSan), a race detector.
+//
+// Interceptors for operators new and delete.
+//===----------------------------------------------------------------------===//
+
+#include "tsan_interceptors.h"
+#include "tsan_mman.h"
+#include "tsan_rtl.h"
+
+#include <stddef.h>
+#include <new>
+
+namespace __tsan {
+// This function is a no-op. We need it to make sure that object file
+// with our replacements will actually be loaded from static TSan
+// run-time library at link-time.
+void ReplaceOperatorsNewAndDelete() { }
+}
+
+using namespace __tsan;  // NOLINT
+
+#define OPERATOR_NEW_BODY(mangled_name) \
+  void *p = 0; \
+  {  \
+    SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
+    p = user_alloc(thr, pc, size); \
+  }  \
+  invoke_malloc_hook(p, size);  \
+  return p;
+
+void *operator new(size_t size) throw(std::bad_alloc) {
+  OPERATOR_NEW_BODY(_Znwm);
+}
+void *operator new[](size_t size) throw(std::bad_alloc) {
+  OPERATOR_NEW_BODY(_Znam);
+}
+void *operator new(size_t size, std::nothrow_t const&) throw() {
+  OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t);
+}
+void *operator new[](size_t size, std::nothrow_t const&) throw() {
+  OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t);
+}
+
+#define OPERATOR_DELETE_BODY(mangled_name) \
+  if (ptr == 0) return;  \
+  invoke_free_hook(ptr);  \
+  SCOPED_INTERCEPTOR_RAW(mangled_name, ptr);  \
+  user_free(thr, pc, ptr);
+
+void operator delete(void *ptr) throw() {
+  OPERATOR_DELETE_BODY(_ZdlPv);
+}
+void operator delete[](void *ptr) throw() {
+  OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);
+}
+void operator delete(void *ptr, std::nothrow_t const&) throw() {
+  OPERATOR_DELETE_BODY(_ZdaPv);
+}
+void operator delete[](void *ptr, std::nothrow_t const&) throw() {
+  OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);
+}

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=164487&r1=164486&r2=164487&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Mon Sep 24 08:19:47 2012
@@ -436,6 +436,7 @@
 void InitializeShadowMemory();
 void InitializeInterceptors();
 void InitializeDynamicAnnotations();
+void ReplaceOperatorsNewAndDelete();
 
 void ReportRace(ThreadState *thr);
 bool OutputReport(const ScopedReport &srep,





More information about the llvm-commits mailing list