summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/tsan/lit_tests/java.h1
-rw-r--r--compiler-rt/lib/tsan/lit_tests/java_alloc.cc1
-rw-r--r--compiler-rt/lib/tsan/lit_tests/java_lock.cc1
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors.cc17
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interface_java.cc14
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interface_java.h6
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).
OpenPOWER on IntegriCloud