[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