[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