summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/tsan/go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2019-09-18 09:18:04 +0000
committerDmitry Vyukov <dvyukov@google.com>2019-09-18 09:18:04 +0000
commitd97865e530df4ad2ed9c2a999edf0a19ee567e79 (patch)
tree3aa3dc079dba0994c64595a2a595d93844df063b /compiler-rt/lib/tsan/go
parentdc2a7f5b39213bdc7574cabd3131ba0215c11e8e (diff)
downloadbcm5719-llvm-d97865e530df4ad2ed9c2a999edf0a19ee567e79.tar.gz
bcm5719-llvm-d97865e530df4ad2ed9c2a999edf0a19ee567e79.zip
tsan: allow the Go runtime to return multiple stack frames for a single PC
This fix allows tsan to report stack traces correctly even in the presence of mid-stack inlining by the Go compiler. See https://go-review.googlesource.com/c/go/+/195781 for the Go runtime side of this change. Author: randall77 (Keith Randall) Reviewed: https://reviews.llvm.org/D67671 llvm-svn: 372205
Diffstat (limited to 'compiler-rt/lib/tsan/go')
-rw-r--r--compiler-rt/lib/tsan/go/tsan_go.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/compiler-rt/lib/tsan/go/tsan_go.cpp b/compiler-rt/lib/tsan/go/tsan_go.cpp
index 271f6bc00cd..f5998c0c781 100644
--- a/compiler-rt/lib/tsan/go/tsan_go.cpp
+++ b/compiler-rt/lib/tsan/go/tsan_go.cpp
@@ -54,20 +54,31 @@ struct SymbolizeCodeContext {
};
SymbolizedStack *SymbolizeCode(uptr addr) {
- SymbolizedStack *s = SymbolizedStack::New(addr);
- SymbolizeCodeContext cbctx;
- internal_memset(&cbctx, 0, sizeof(cbctx));
- cbctx.pc = addr;
- go_runtime_cb(CallbackSymbolizeCode, &cbctx);
- if (cbctx.res) {
+ SymbolizedStack *first = SymbolizedStack::New(addr);
+ SymbolizedStack *s = first;
+ for (;;) {
+ SymbolizeCodeContext cbctx;
+ internal_memset(&cbctx, 0, sizeof(cbctx));
+ cbctx.pc = addr;
+ go_runtime_cb(CallbackSymbolizeCode, &cbctx);
+ if (cbctx.res == 0)
+ break;
AddressInfo &info = s->info;
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;
+
+ if (cbctx.pc == addr) // outermost (non-inlined) function
+ break;
+ addr = cbctx.pc;
+ // Allocate a stack entry for the parent of the inlined function.
+ SymbolizedStack *s2 = SymbolizedStack::New(addr);
+ s->next = s2;
+ s = s2;
}
- return s;
+ return first;
}
struct SymbolizeDataContext {
OpenPOWER on IntegriCloud