Skip to content

Commit d97865e

Browse files
committed
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
1 parent dc2a7f5 commit d97865e

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

compiler-rt/lib/tsan/go/tsan_go.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,31 @@ struct SymbolizeCodeContext {
5454
};
5555

5656
SymbolizedStack *SymbolizeCode(uptr addr) {
57-
SymbolizedStack *s = SymbolizedStack::New(addr);
58-
SymbolizeCodeContext cbctx;
59-
internal_memset(&cbctx, 0, sizeof(cbctx));
60-
cbctx.pc = addr;
61-
go_runtime_cb(CallbackSymbolizeCode, &cbctx);
62-
if (cbctx.res) {
57+
SymbolizedStack *first = SymbolizedStack::New(addr);
58+
SymbolizedStack *s = first;
59+
for (;;) {
60+
SymbolizeCodeContext cbctx;
61+
internal_memset(&cbctx, 0, sizeof(cbctx));
62+
cbctx.pc = addr;
63+
go_runtime_cb(CallbackSymbolizeCode, &cbctx);
64+
if (cbctx.res == 0)
65+
break;
6366
AddressInfo &info = s->info;
6467
info.module_offset = cbctx.off;
6568
info.function = internal_strdup(cbctx.func ? cbctx.func : "??");
6669
info.file = internal_strdup(cbctx.file ? cbctx.file : "-");
6770
info.line = cbctx.line;
6871
info.column = 0;
72+
73+
if (cbctx.pc == addr) // outermost (non-inlined) function
74+
break;
75+
addr = cbctx.pc;
76+
// Allocate a stack entry for the parent of the inlined function.
77+
SymbolizedStack *s2 = SymbolizedStack::New(addr);
78+
s->next = s2;
79+
s = s2;
6980
}
70-
return s;
81+
return first;
7182
}
7283

7384
struct SymbolizeDataContext {

0 commit comments

Comments
 (0)