[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