diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2019-09-18 09:18:04 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2019-09-18 09:18:04 +0000 |
commit | d97865e530df4ad2ed9c2a999edf0a19ee567e79 (patch) | |
tree | 3aa3dc079dba0994c64595a2a595d93844df063b /compiler-rt/lib/tsan/go | |
parent | dc2a7f5b39213bdc7574cabd3131ba0215c11e8e (diff) | |
download | bcm5719-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.cpp | 25 |
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 { |