[compiler-rt] 5237b14 - tsan: print alloc stack for Java objects
Dmitry Vyukov via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 28 11:25:16 PDT 2021
Author: Dmitry Vyukov
Date: 2021-07-28T20:25:11+02:00
New Revision: 5237b140874a47670678b1f5b4566ffcea15b9b7
URL: https://github.com/llvm/llvm-project/commit/5237b140874a47670678b1f5b4566ffcea15b9b7
DIFF: https://github.com/llvm/llvm-project/commit/5237b140874a47670678b1f5b4566ffcea15b9b7.diff
LOG: tsan: print alloc stack for Java objects
We maintain information about Java allocations,
but for some reason never printed it in reports.
Print it.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D106956
Added:
Modified:
compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
compiler-rt/lib/tsan/rtl/tsan_rtl.h
compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
compiler-rt/test/tsan/java.h
compiler-rt/test/tsan/java_symbolization.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
index a9d817d5c0f5..72595527989b 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
@@ -54,6 +54,23 @@ class ScopedJavaFunc {
static u64 jctx_buf[sizeof(JavaContext) / sizeof(u64) + 1];
static JavaContext *jctx;
+MBlock *JavaHeapBlock(uptr addr, uptr *start) {
+ if (!jctx || addr < jctx->heap_begin ||
+ addr >= jctx->heap_begin + jctx->heap_size)
+ return nullptr;
+ for (uptr p = RoundDown(addr, kMetaShadowCell); p >= jctx->heap_begin;
+ p -= kMetaShadowCell) {
+ MBlock *b = ctx->metamap.GetBlock(p);
+ if (!b)
+ continue;
+ if (p + b->siz <= addr)
+ return nullptr;
+ *start = p;
+ return b;
+ }
+ return nullptr;
+}
+
} // namespace __tsan
#define SCOPED_JAVA_FUNC(func) \
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
index 7c322c23edf7..48d2d0307caf 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
@@ -683,6 +683,7 @@ u32 CurrentStackId(ThreadState *thr, uptr pc);
ReportStack *SymbolizeStackId(u32 stack_id);
void PrintCurrentStack(ThreadState *thr, uptr pc);
void PrintCurrentStackSlow(uptr pc); // uses libunwind
+MBlock *JavaHeapBlock(uptr addr, uptr *start);
void Initialize(ThreadState *thr);
void MaybeSpawnBackgroundThread();
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
index 5c656b2d3e70..708ee7f21708 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
@@ -337,12 +337,15 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) {
return;
}
MBlock *b = 0;
+ uptr block_begin = 0;
Allocator *a = allocator();
if (a->PointerIsMine((void*)addr)) {
- void *block_begin = a->GetBlockBegin((void*)addr);
+ block_begin = (uptr)a->GetBlockBegin((void *)addr);
if (block_begin)
- b = ctx->metamap.GetBlock((uptr)block_begin);
+ b = ctx->metamap.GetBlock(block_begin);
}
+ if (!b)
+ b = JavaHeapBlock(addr, &block_begin);
if (b != 0) {
ThreadContext *tctx = FindThreadByTidLocked(b->tid);
ReportLocation *loc = ReportLocation::New(ReportLocationHeap);
diff --git a/compiler-rt/test/tsan/java.h b/compiler-rt/test/tsan/java.h
index 765bae0e80b0..9df7fb6f9fcc 100644
--- a/compiler-rt/test/tsan/java.h
+++ b/compiler-rt/test/tsan/java.h
@@ -22,6 +22,8 @@ int __tsan_java_release_store(jptr addr);
void __tsan_read1_pc(jptr addr, jptr pc);
void __tsan_write1_pc(jptr addr, jptr pc);
+void __tsan_func_entry(jptr pc);
+void __tsan_func_exit();
}
const jptr kExternalPCBit = 1ULL << 60;
diff --git a/compiler-rt/test/tsan/java_symbolization.cpp b/compiler-rt/test/tsan/java_symbolization.cpp
index f82bd5ead48e..cdc9782c8ec0 100644
--- a/compiler-rt/test/tsan/java_symbolization.cpp
+++ b/compiler-rt/test/tsan/java_symbolization.cpp
@@ -9,24 +9,40 @@ extern "C" void __tsan_symbolize_external_ex(
add_frame(ctx, "MyInnerFunc", "MyInnerFile.java", 1234, 56);
add_frame(ctx, "MyOuterFunc", "MyOuterFile.java", 4321, 65);
}
+ if (pc == (2345 | kExternalPCBit)) {
+ add_frame(ctx, "Caller1", "CallerFile.java", 111, 22);
+ add_frame(ctx, "Caller2", "CallerFile.java", 333, 44);
+ }
+ if (pc == (3456 | kExternalPCBit)) {
+ add_frame(ctx, "Allocer1", "Alloc.java", 11, 222);
+ add_frame(ctx, "Allocer2", "Alloc.java", 33, 444);
+ }
}
void *Thread(void *p) {
barrier_wait(&barrier);
- __tsan_write1_pc((jptr)p, 1234 | kExternalPCBit);
+ __tsan_func_entry(2345 | kExternalPCBit);
+ __tsan_write1_pc((jptr)p + 16, 1234 | kExternalPCBit);
+ __tsan_func_exit();
return 0;
}
+jptr const kHeapSize = 64 * 1024;
+jptr java_heap[kHeapSize];
+
int main() {
barrier_init(&barrier, 2);
- int const kHeapSize = 1024 * 1024;
- jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
+ jptr jheap = (jptr)java_heap;
__tsan_java_init(jheap, kHeapSize);
- const int kBlockSize = 16;
+ const int kBlockSize = 32;
+ __tsan_func_entry(3456 | kExternalPCBit);
__tsan_java_alloc(jheap, kBlockSize);
+ __tsan_func_exit();
pthread_t th;
pthread_create(&th, 0, Thread, (void*)jheap);
- __tsan_write1_pc((jptr)jheap, 1234 | kExternalPCBit);
+ __tsan_func_entry(2345 | kExternalPCBit);
+ __tsan_write1_pc(jheap + 16, 1234 | kExternalPCBit);
+ __tsan_func_exit();
barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(jheap, kBlockSize);
@@ -35,6 +51,24 @@ int main() {
}
// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Write
+// CHECK: #0 MyInnerFunc MyInnerFile.java:1234:56
+// CHECK: #1 MyOuterFunc MyOuterFile.java:4321:65
+// CHECK: #2 Caller1 CallerFile.java:111:22
+// CHECK: #3 Caller2 CallerFile.java:333:44
+// CHECK-NOT: #4
+// CHECK: Previous write
// CHECK: #0 MyInnerFunc MyInnerFile.java:1234:56
// CHECK: #1 MyOuterFunc MyOuterFile.java:4321:65
+// CHECK: #2 Caller1 CallerFile.java:111:22
+// CHECK: #3 Caller2 CallerFile.java:333:44
+// On Linux/glibc #4 is __libc_start_main, but can be something else elsewhere.
+// CHECK: #4
+// CHECK: Location is heap block of size 32 at {{.*}} allocated by main thread:
+// CHECK: #0 __tsan_java_alloc
+// CHECK: #1 main
+// CHECK: #2 Allocer1 Alloc.java:11:222
+// CHECK: #3 Allocer2 Alloc.java:33:444
+// On Linux/glibc #4 is __libc_start_main, but can be something else elsewhere.
+// CHECK: #4
// CHECK: DONE
More information about the llvm-commits
mailing list