Skip to content

Commit 1328352

Browse files
committed
compiler-rt/lib/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 golang/go#33309
1 parent 8626a35 commit 1328352

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

lib/tsan/go/tsan_go.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,33 @@ 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+
while(true) {
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;
66+
}
6367
AddressInfo &info = s->info;
6468
info.module_offset = cbctx.off;
6569
info.function = internal_strdup(cbctx.func ? cbctx.func : "??");
6670
info.file = internal_strdup(cbctx.file ? cbctx.file : "-");
6771
info.line = cbctx.line;
6872
info.column = 0;
73+
74+
if (cbctx.pc == addr) { // outermost (non-inlined) function
75+
break;
76+
}
77+
addr = cbctx.pc;
78+
// Allocate a stack entry for the parent of the inlined function.
79+
SymbolizedStack *s2 = SymbolizedStack::New(addr);
80+
s->next = s2;
81+
s = s2;
6982
}
70-
return s;
83+
return first;
7184
}
7285

7386
struct SymbolizeDataContext {

0 commit comments

Comments
 (0)