[compiler-rt] r191152 - tsan: ignore all interceptors coming directly from JVM

Dmitry Vyukov dvyukov at google.com
Sat Sep 21 16:06:01 PDT 2013


Author: dvyukov
Date: Sat Sep 21 18:06:00 2013
New Revision: 191152

URL: http://llvm.org/viewvc/llvm-project?rev=191152&view=rev
Log:
tsan: ignore all interceptors coming directly from JVM

Modified:
    compiler-rt/trunk/lib/tsan/lit_tests/java.h
    compiler-rt/trunk/lib/tsan/lit_tests/java_alloc.cc
    compiler-rt/trunk/lib/tsan/lit_tests/java_lock.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.h

Modified: compiler-rt/trunk/lib/tsan/lit_tests/java.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/java.h?rev=191152&r1=191151&r2=191152&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/lit_tests/java.h (original)
+++ compiler-rt/trunk/lib/tsan/lit_tests/java.h Sat Sep 21 18:06:00 2013
@@ -5,6 +5,7 @@
 
 extern "C" {
 typedef unsigned long jptr;  // NOLINT
+void __tsan_java_preinit(const char *libjvm_path);
 void __tsan_java_init(jptr heap_begin, jptr heap_size);
 int  __tsan_java_fini();
 void __tsan_java_alloc(jptr ptr, jptr size);

Modified: compiler-rt/trunk/lib/tsan/lit_tests/java_alloc.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/java_alloc.cc?rev=191152&r1=191151&r2=191152&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/lit_tests/java_alloc.cc (original)
+++ compiler-rt/trunk/lib/tsan/lit_tests/java_alloc.cc Sat Sep 21 18:06:00 2013
@@ -20,6 +20,7 @@ void *Thread(void *p) {
 
 int main() {
   jptr jheap = (jptr)malloc(kHeapSize);
+  __tsan_java_preinit("[vdso]");
   __tsan_java_init(jheap, kHeapSize);
   pthread_t th;
   pthread_create(&th, 0, Thread, (void*)(jheap + kHeapSize / 4));

Modified: compiler-rt/trunk/lib/tsan/lit_tests/java_lock.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/java_lock.cc?rev=191152&r1=191151&r2=191152&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/lit_tests/java_lock.cc (original)
+++ compiler-rt/trunk/lib/tsan/lit_tests/java_lock.cc Sat Sep 21 18:06:00 2013
@@ -16,6 +16,7 @@ void *Thread(void *p) {
 int main() {
   int const kHeapSize = 1024 * 1024;
   void *jheap = malloc(kHeapSize);
+  __tsan_java_preinit(0);
   __tsan_java_init((jptr)jheap, kHeapSize);
   const int kBlockSize = 16;
   __tsan_java_alloc((jptr)jheap, kBlockSize);

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=191152&r1=191151&r2=191152&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Sat Sep 21 18:06:00 2013
@@ -128,6 +128,21 @@ struct SignalContext {
   int pending_signal_count;
   SignalDesc pending_signals[kSigCount];
 };
+
+// Used to ignore interceptors coming directly from libjvm.so.
+atomic_uintptr_t libjvm_begin;
+atomic_uintptr_t libjvm_end;
+
+static bool libjvm_check(uptr pc) {
+  uptr begin = atomic_load(&libjvm_begin, memory_order_relaxed);
+  if (begin != 0 && pc >= begin) {
+    uptr end = atomic_load(&libjvm_end, memory_order_relaxed);
+    if (end != 0 && pc < end)
+      return true;
+  }
+  return false;
+}
+
 }  // namespace __tsan
 
 static SignalContext *SigCtx(ThreadState *thr) {
@@ -191,7 +206,7 @@ ScopedInterceptor::~ScopedInterceptor()
       Printf("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \
       Die(); \
     } \
-    if (thr->in_rtl > 1) \
+    if (thr->in_rtl > 1 || libjvm_check(pc)) \
       return REAL(func)(__VA_ARGS__); \
 /**/
 

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.cc?rev=191152&r1=191151&r2=191152&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.cc Sat Sep 21 18:06:00 2013
@@ -18,6 +18,7 @@
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_placement_new.h"
 #include "sanitizer_common/sanitizer_stacktrace.h"
+#include "sanitizer_common/sanitizer_procmaps.h"
 
 using namespace __tsan;  // NOLINT
 
@@ -95,6 +96,8 @@ class ScopedJavaFunc {
 
 static u64 jctx_buf[sizeof(JavaContext) / sizeof(u64) + 1];
 static JavaContext *jctx;
+extern atomic_uintptr_t libjvm_begin;
+extern atomic_uintptr_t libjvm_end;
 
 static BlockDesc *getblock(uptr addr) {
   uptr i = (addr - jctx->heap_begin) / kHeapAlignment;
@@ -163,6 +166,17 @@ SyncVar* GetAndRemoveJavaSync(ThreadStat
   ScopedJavaFunc scoped(thr, caller_pc); \
 /**/
 
+void __tsan_java_preinit(const char *libjvm_path) {
+  SCOPED_JAVA_FUNC(__tsan_java_preinit);
+  if (libjvm_path) {
+    uptr begin, end;
+    if (GetCodeRangeForFile(libjvm_path, &begin, &end)) {
+      atomic_store(&libjvm_begin, begin, memory_order_relaxed);
+      atomic_store(&libjvm_end, end, memory_order_relaxed);
+    }
+  }
+}
+
 void __tsan_java_init(jptr heap_begin, jptr heap_size) {
   SCOPED_JAVA_FUNC(__tsan_java_init);
   DPrintf("#%d: java_init(%p, %p)\n", thr->tid, heap_begin, heap_size);

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.h?rev=191152&r1=191151&r2=191152&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.h Sat Sep 21 18:06:00 2013
@@ -34,7 +34,11 @@ extern "C" {
 
 typedef unsigned long jptr;  // NOLINT
 
-// Must be called before any other callback from Java.
+// Must be called before any other callback from Java, right after dlopen
+// of JVM shared lib. If libjvm_path is specified, then all interceptors
+// coming directly from JVM will be ignored.
+void __tsan_java_preinit(const char *libjvm_path) INTERFACE_ATTRIBUTE;
+// Must be called after __tsan_java_preinit but before any other callback.
 void __tsan_java_init(jptr heap_begin, jptr heap_size) INTERFACE_ATTRIBUTE;
 // Must be called when the application exits.
 // Not necessary the last callback (concurrently running threads are OK).





More information about the llvm-commits mailing list