aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/race.go
diff options
context:
space:
mode:
authorKeith Randall <khr@google.com>2019-09-16 14:38:12 -0700
committerKeith Randall <khr@golang.org>2019-09-23 16:50:00 +0000
commita14efb1be3a59dffbf4dd9121191d6d656049564 (patch)
tree495e090dede94f044caa36cd3169e76806772816 /src/runtime/race.go
parent870080752d175d5cede350486acf36213c64f35c (diff)
downloadgo-a14efb1be3a59dffbf4dd9121191d6d656049564.tar.gz
go-a14efb1be3a59dffbf4dd9121191d6d656049564.zip
runtime: allow the Go runtime to return multiple stack frames for a single PC
Upgrade the thread sanitizer to handle mid-stack inlining correctly. We can now return multiple stack frames for each pc that the thread sanitizer gives us to symbolize. To fix #33309, we still need to modify the tsan library with its portion of this fix, rebuild the .syso files on all supported archs, and check them into runtime/race. Update #33309 Change-Id: I340013631ffc8428043ab7efe3a41b6bf5638eaf Reviewed-on: https://go-review.googlesource.com/c/go/+/195781 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Diffstat (limited to 'src/runtime/race.go')
-rw-r--r--src/runtime/race.go44
1 files changed, 40 insertions, 4 deletions
diff --git a/src/runtime/race.go b/src/runtime/race.go
index c41e1ba222..d2fc6a3c47 100644
--- a/src/runtime/race.go
+++ b/src/runtime/race.go
@@ -155,15 +155,51 @@ func racecallback(cmd uintptr, ctx unsafe.Pointer) {
}
}
+// raceSymbolizeCode reads ctx.pc and populates the rest of *ctx with
+// information about the code at that pc.
+//
+// The race detector has already subtracted 1 from pcs, so they point to the last
+// byte of call instructions (including calls to runtime.racewrite and friends).
+//
+// If the incoming pc is part of an inlined function, *ctx is populated
+// with information about the inlined function, and on return ctx.pc is set
+// to a pc in the logically containing function. (The race detector should call this
+// function again with that pc.)
+//
+// If the incoming pc is not part of an inlined function, the return pc is unchanged.
func raceSymbolizeCode(ctx *symbolizeCodeContext) {
- f := findfunc(ctx.pc)._Func()
+ pc := ctx.pc
+ fi := findfunc(pc)
+ f := fi._Func()
if f != nil {
- file, line := f.FileLine(ctx.pc)
+ file, line := f.FileLine(pc)
if line != 0 {
- ctx.fn = cfuncname(f.funcInfo())
+ if inldata := funcdata(fi, _FUNCDATA_InlTree); inldata != nil {
+ inltree := (*[1 << 20]inlinedCall)(inldata)
+ for {
+ ix := pcdatavalue(fi, _PCDATA_InlTreeIndex, pc, nil)
+ if ix >= 0 {
+ if inltree[ix].funcID == funcID_wrapper {
+ // ignore wrappers
+ // Back up to an instruction in the "caller".
+ pc = f.Entry() + uintptr(inltree[ix].parentPc)
+ continue
+ }
+ ctx.pc = f.Entry() + uintptr(inltree[ix].parentPc) // "caller" pc
+ ctx.fn = cfuncnameFromNameoff(fi, inltree[ix].func_)
+ ctx.line = uintptr(line)
+ ctx.file = &bytes(file)[0] // assume NUL-terminated
+ ctx.off = pc - f.Entry()
+ ctx.res = 1
+ return
+ }
+ break
+ }
+ }
+ ctx.fn = cfuncname(fi)
ctx.line = uintptr(line)
ctx.file = &bytes(file)[0] // assume NUL-terminated
- ctx.off = ctx.pc - f.Entry()
+ ctx.off = pc - f.Entry()
ctx.res = 1
return
}