[compiler-rt] r262343 - tsan: describe heap/data locations in Go

Dmitry Vyukov via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 1 07:38:13 PST 2016


Author: dvyukov
Date: Tue Mar  1 09:38:12 2016
New Revision: 262343

URL: http://llvm.org/viewvc/llvm-project?rev=262343&view=rev
Log:
tsan: describe heap/data locations in Go


Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h
    compiler-rt/trunk/lib/tsan/go/test.c
    compiler-rt/trunk/lib/tsan/go/tsan_go.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc?rev=262343&r1=262342&r2=262343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc Tue Mar  1 09:38:12 2016
@@ -60,6 +60,7 @@ DataInfo::DataInfo() {
 
 void DataInfo::Clear() {
   InternalFree(module);
+  InternalFree(file);
   InternalFree(name);
   internal_memset(this, 0, sizeof(DataInfo));
 }

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h?rev=262343&r1=262342&r2=262343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h Tue Mar  1 09:38:12 2016
@@ -65,6 +65,8 @@ struct DataInfo {
   // (de)allocated using sanitizer internal allocator.
   char *module;
   uptr module_offset;
+  char *file;
+  uptr line;
   char *name;
   uptr start;
   uptr size;

Modified: compiler-rt/trunk/lib/tsan/go/test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/go/test.c?rev=262343&r1=262342&r2=262343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/go/test.c (original)
+++ compiler-rt/trunk/lib/tsan/go/test.c Tue Mar  1 09:38:12 2016
@@ -13,7 +13,7 @@
 
 #include <stdio.h>
 
-void __tsan_init(void **thr, void (*cb)(void*));
+void __tsan_init(void **thr, void (*cb)(long, void*));
 void __tsan_fini();
 void __tsan_map_shadow(void *addr, unsigned long size);
 void __tsan_go_start(void *thr, void **chthr, void *pc);
@@ -22,12 +22,12 @@ void __tsan_read(void *thr, void *addr,
 void __tsan_write(void *thr, void *addr, void *pc);
 void __tsan_func_enter(void *thr, void *pc);
 void __tsan_func_exit(void *thr);
-void __tsan_malloc(void *p, unsigned long sz);
+void __tsan_malloc(void *thr, void *pc, void *p, unsigned long sz);
 void __tsan_acquire(void *thr, void *addr);
 void __tsan_release(void *thr, void *addr);
 void __tsan_release_merge(void *thr, void *addr);
 
-void symbolize_cb(void *ctx) {}
+void symbolize_cb(long cmd, void *ctx) {}
 
 char buf0[100<<10];
 
@@ -36,12 +36,13 @@ void barfoo() {}
 
 int main(void) {
   void *thr0 = 0;
-  char *buf = (char*)((unsigned long)buf0 + (64<<10) - 1 & ~((64<<10) - 1));
-  __tsan_malloc(buf, 10);
   __tsan_init(&thr0, symbolize_cb);
+  char *buf = (char*)((unsigned long)buf0 + (64<<10) - 1 & ~((64<<10) - 1));
   __tsan_map_shadow(buf, 4096);
+  __tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10);
+  __tsan_free(thr0, buf, 10);
   __tsan_func_enter(thr0, (char*)&main + 1);
-  __tsan_malloc(buf, 10);
+  __tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10);
   __tsan_release(thr0, buf);
   __tsan_release_merge(thr0, buf);
   void *thr1 = 0;

Modified: compiler-rt/trunk/lib/tsan/go/tsan_go.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/go/tsan_go.cc?rev=262343&r1=262342&r2=262343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/go/tsan_go.cc (original)
+++ compiler-rt/trunk/lib/tsan/go/tsan_go.cc Tue Mar  1 09:38:12 2016
@@ -28,10 +28,6 @@ bool IsExpectedReport(uptr addr, uptr si
   return false;
 }
 
-ReportLocation *SymbolizeData(uptr addr) {
-  return 0;
-}
-
 void *internal_alloc(MBlockType typ, uptr sz) {
   return InternalAlloc(sz);
 }
@@ -40,7 +36,15 @@ void internal_free(void *p) {
   InternalFree(p);
 }
 
-struct SymbolizeContext {
+// Callback into Go.
+static void (*go_runtime_cb)(uptr cmd, void *ctx);
+
+enum {
+  CallbackSymbolizeCode = 0,
+  CallbackSymbolizeData = 1,
+};
+
+struct SymbolizeCodeContext {
   uptr pc;
   char *func;
   char *file;
@@ -49,26 +53,62 @@ struct SymbolizeContext {
   uptr res;
 };
 
-// Callback into Go.
-static void (*symbolize_cb)(SymbolizeContext *ctx);
-
 SymbolizedStack *SymbolizeCode(uptr addr) {
   SymbolizedStack *s = SymbolizedStack::New(addr);
-  SymbolizeContext ctx;
-  internal_memset(&ctx, 0, sizeof(ctx));
-  ctx.pc = addr;
-  symbolize_cb(&ctx);
-  if (ctx.res) {
+  SymbolizeCodeContext cbctx;
+  internal_memset(&cbctx, 0, sizeof(cbctx));
+  cbctx.pc = addr;
+  go_runtime_cb(CallbackSymbolizeCode, &cbctx);
+  if (cbctx.res) {
     AddressInfo &info = s->info;
-    info.module_offset = ctx.off;
-    info.function = internal_strdup(ctx.func ? ctx.func : "??");
-    info.file = internal_strdup(ctx.file ? ctx.file : "-");
-    info.line = ctx.line;
+    info.module_offset = cbctx.off;
+    info.function = internal_strdup(cbctx.func ? cbctx.func : "??");
+    info.file = internal_strdup(cbctx.file ? cbctx.file : "-");
+    info.line = cbctx.line;
     info.column = 0;
   }
   return s;
 }
 
+struct SymbolizeDataContext {
+  uptr addr;
+  uptr heap;
+  uptr start;
+  uptr size;
+  char *name;
+  char *file;
+  uptr line;
+  uptr res;
+};
+
+ReportLocation *SymbolizeData(uptr addr) {
+  SymbolizeDataContext cbctx;
+  internal_memset(&cbctx, 0, sizeof(cbctx));
+  cbctx.addr = addr;
+  go_runtime_cb(CallbackSymbolizeData, &cbctx);
+  if (!cbctx.res)
+    return 0;
+  if (cbctx.heap) {
+    MBlock *b = ctx->metamap.GetBlock(cbctx.start);
+    if (!b)
+      return 0;
+    ReportLocation *loc = ReportLocation::New(ReportLocationHeap);
+    loc->heap_chunk_start = cbctx.start;
+    loc->heap_chunk_size = b->siz;
+    loc->tid = b->tid;
+    loc->stack = SymbolizeStackId(b->stk);
+    return loc;
+  } else {
+    ReportLocation *loc = ReportLocation::New(ReportLocationGlobal);
+    loc->global.name = internal_strdup(cbctx.name ? cbctx.name : "??");
+    loc->global.file = internal_strdup(cbctx.file ? cbctx.file : "??");
+    loc->global.line = cbctx.line;
+    loc->global.start = cbctx.start;
+    loc->global.size = cbctx.size;
+    return loc;
+  }
+}
+
 extern "C" {
 
 static ThreadState *main_thr;
@@ -81,8 +121,8 @@ static ThreadState *AllocGoroutine() {
   return thr;
 }
 
-void __tsan_init(ThreadState **thrp, void (*cb)(SymbolizeContext *cb)) {
-  symbolize_cb = cb;
+void __tsan_init(ThreadState **thrp, void (*cb)(uptr cmd, void *cb)) {
+  go_runtime_cb = cb;
   ThreadState *thr = AllocGoroutine();
   main_thr = *thrp = thr;
   Initialize(thr);
@@ -140,12 +180,18 @@ void __tsan_func_exit(ThreadState *thr)
   FuncExit(thr);
 }
 
-void __tsan_malloc(void *p, uptr sz) {
-  if (!inited)
-    return;
+void __tsan_malloc(ThreadState *thr, uptr pc, uptr p, uptr sz) {
+  CHECK(inited);
+  if (thr && pc)
+    ctx->metamap.AllocBlock(thr, pc, p, sz);
   MemoryResetRange(0, 0, (uptr)p, sz);
 }
 
+void __tsan_free(ThreadState *thr, uptr p, uptr sz) {
+  if (thr)
+    ctx->metamap.FreeRange(thr, 0, p, sz);
+}
+
 void __tsan_go_start(ThreadState *parent, ThreadState **pthr, void *pc) {
   ThreadState *thr = AllocGoroutine();
   *pthr = thr;

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=262343&r1=262342&r2=262343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Tue Mar  1 09:38:12 2016
@@ -379,9 +379,9 @@ void PrintStack(const ReportStack *ent)
 
 static void PrintMop(const ReportMop *mop, bool first) {
   Printf("\n");
-  Printf("%s by ",
+  Printf("%s at %p by ",
       (first ? (mop->write ? "Write" : "Read")
-             : (mop->write ? "Previous write" : "Previous read")));
+             : (mop->write ? "Previous write" : "Previous read")), mop->addr);
   if (mop->tid == kMainThreadId)
     Printf("main goroutine:\n");
   else
@@ -389,6 +389,31 @@ static void PrintMop(const ReportMop *mo
   PrintStack(mop->stack);
 }
 
+static void PrintLocation(const ReportLocation *loc) {
+  switch (loc->type) {
+  case ReportLocationHeap: {
+    Printf("\n");
+    Printf("Heap block of size %zu at %p allocated by ",
+        loc->heap_chunk_size, loc->heap_chunk_start);
+    if (loc->tid == kMainThreadId)
+      Printf("main goroutine:\n");
+    else
+      Printf("goroutine %d:\n", loc->tid);
+    PrintStack(loc->stack);
+    break;
+  }
+  case ReportLocationGlobal: {
+    Printf("\n");
+    Printf("Global var %s of size %zu at %p declared at %s:%zu\n",
+        loc->global.name, loc->global.size, loc->global.start,
+        loc->global.file, loc->global.line);
+    break;
+  }
+  default:
+    break;
+  }
+}
+
 static void PrintThread(const ReportThread *rt) {
   if (rt->id == kMainThreadId)
     return;
@@ -404,6 +429,8 @@ void PrintReport(const ReportDesc *rep)
     Printf("WARNING: DATA RACE");
     for (uptr i = 0; i < rep->mops.Size(); i++)
       PrintMop(rep->mops[i], i == 0);
+    for (uptr i = 0; i < rep->locs.Size(); i++)
+      PrintLocation(rep->locs[i]);
     for (uptr i = 0; i < rep->threads.Size(); i++)
       PrintThread(rep->threads[i]);
   } else if (rep->typ == ReportTypeDeadlock) {

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=262343&r1=262342&r2=262343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc Tue Mar  1 09:38:12 2016
@@ -342,12 +342,12 @@ void ScopedReport::AddLocation(uptr addr
     rep_->locs.PushBack(loc);
     AddThread(tctx);
   }
+#endif
   if (ReportLocation *loc = SymbolizeData(addr)) {
     loc->suppressable = true;
     rep_->locs.PushBack(loc);
     return;
   }
-#endif
 }
 
 #ifndef SANITIZER_GO




More information about the llvm-commits mailing list