aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2018-01-30 16:01:33 -0500
committerAustin Clements <austin@google.com>2018-01-31 02:13:19 +0000
commit5c2be42a687492d2538489de69c50d66fd3dadee (patch)
treee765ac5323a0c76750e198d76a27aece7dd10427 /src/runtime
parent03e10bd9c4d33a68cd98931e8a4c644e8274b094 (diff)
downloadgo-5c2be42a687492d2538489de69c50d66fd3dadee.tar.xz
runtime: don't unwind past asmcgocall
asmcgocall switches to the system stack and aligns the SP, so gentraceback both can't unwind over it when it appears on the system stack (it'll read some uninitialized stack slot as the return PC). There's also no point in unwinding over it, so don't. Updates #23576. Change-Id: Idfcc9599c7636b80dec5451cb65ae892b4611981 Reviewed-on: https://go-review.googlesource.com/90895 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/traceback.go14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index 62622df2e7..0d5b06a1f0 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -43,6 +43,7 @@ var (
morestackPC uintptr
mstartPC uintptr
rt0_goPC uintptr
+ asmcgocallPC uintptr
sigpanicPC uintptr
runfinqPC uintptr
bgsweepPC uintptr
@@ -70,6 +71,7 @@ func tracebackinit() {
morestackPC = funcPC(morestack)
mstartPC = funcPC(mstart)
rt0_goPC = funcPC(rt0_go)
+ asmcgocallPC = funcPC(asmcgocall)
sigpanicPC = funcPC(sigpanic)
runfinqPC = funcPC(runfinq)
bgsweepPC = funcPC(bgsweep)
@@ -251,7 +253,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
}
}
var flr funcInfo
- if topofstack(f) {
+ if topofstack(f, gp.m != nil && gp == gp.m.g0) {
frame.lr = 0
flr = funcInfo{}
} else if usesLR && f.entry == jmpdeferPC {
@@ -920,14 +922,20 @@ func tracebackHexdump(stk stack, frame *stkframe, bad uintptr) {
}
// Does f mark the top of a goroutine stack?
-func topofstack(f funcInfo) bool {
+func topofstack(f funcInfo, g0 bool) bool {
pc := f.entry
return pc == goexitPC ||
pc == mstartPC ||
pc == mcallPC ||
pc == morestackPC ||
pc == rt0_goPC ||
- externalthreadhandlerp != 0 && pc == externalthreadhandlerp
+ externalthreadhandlerp != 0 && pc == externalthreadhandlerp ||
+ // asmcgocall is TOS on the system stack because it
+ // switches to the system stack, but in this case we
+ // can come back to the regular stack and still want
+ // to be able to unwind through the call that appeared
+ // on the regular stack.
+ (g0 && pc == asmcgocallPC)
}
// isSystemGoroutine reports whether the goroutine g must be omitted in