diff options
-rw-r--r-- | compiler-rt/lib/tsan/lit_tests/java.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/lit_tests/java_alloc.cc | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/lit_tests/java_lock.cc | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interceptors.cc | 17 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interface_java.cc | 14 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interface_java.h | 6 |
6 files changed, 38 insertions, 2 deletions
diff --git a/compiler-rt/lib/tsan/lit_tests/java.h b/compiler-rt/lib/tsan/lit_tests/java.h index 04094197edb..7aa0bca32ce 100644 --- a/compiler-rt/lib/tsan/lit_tests/java.h +++ b/compiler-rt/lib/tsan/lit_tests/java.h @@ -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); diff --git a/compiler-rt/lib/tsan/lit_tests/java_alloc.cc b/compiler-rt/lib/tsan/lit_tests/java_alloc.cc index 4dbce70c31e..079c9b92a62 100644 --- a/compiler-rt/lib/tsan/lit_tests/java_alloc.cc +++ b/compiler-rt/lib/tsan/lit_tests/java_alloc.cc @@ -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)); diff --git a/compiler-rt/lib/tsan/lit_tests/java_lock.cc b/compiler-rt/lib/tsan/lit_tests/java_lock.cc index d9db103504d..c01959719b8 100644 --- a/compiler-rt/lib/tsan/lit_tests/java_lock.cc +++ b/compiler-rt/lib/tsan/lit_tests/java_lock.cc @@ -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); diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc index 0338f5a7734..e5bc53316dd 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc @@ -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__); \ /**/ diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cc b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cc index 358fd15ddef..2ac3249acf5 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cc @@ -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(ThreadState *thr, uptr pc, uptr addr) { 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); diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_java.h b/compiler-rt/lib/tsan/rtl/tsan_interface_java.h index 9ac78e074bb..a4a05aa2f5b 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interface_java.h +++ b/compiler-rt/lib/tsan/rtl/tsan_interface_java.h @@ -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). |