Commit 5c2be42a authored by Austin Clements's avatar Austin Clements

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: 's avatarIan Lance Taylor <iant@golang.org>
parent 03e10bd9
...@@ -43,6 +43,7 @@ var ( ...@@ -43,6 +43,7 @@ var (
morestackPC uintptr morestackPC uintptr
mstartPC uintptr mstartPC uintptr
rt0_goPC uintptr rt0_goPC uintptr
asmcgocallPC uintptr
sigpanicPC uintptr sigpanicPC uintptr
runfinqPC uintptr runfinqPC uintptr
bgsweepPC uintptr bgsweepPC uintptr
...@@ -70,6 +71,7 @@ func tracebackinit() { ...@@ -70,6 +71,7 @@ func tracebackinit() {
morestackPC = funcPC(morestack) morestackPC = funcPC(morestack)
mstartPC = funcPC(mstart) mstartPC = funcPC(mstart)
rt0_goPC = funcPC(rt0_go) rt0_goPC = funcPC(rt0_go)
asmcgocallPC = funcPC(asmcgocall)
sigpanicPC = funcPC(sigpanic) sigpanicPC = funcPC(sigpanic)
runfinqPC = funcPC(runfinq) runfinqPC = funcPC(runfinq)
bgsweepPC = funcPC(bgsweep) bgsweepPC = funcPC(bgsweep)
...@@ -251,7 +253,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in ...@@ -251,7 +253,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
} }
} }
var flr funcInfo var flr funcInfo
if topofstack(f) { if topofstack(f, gp.m != nil && gp == gp.m.g0) {
frame.lr = 0 frame.lr = 0
flr = funcInfo{} flr = funcInfo{}
} else if usesLR && f.entry == jmpdeferPC { } else if usesLR && f.entry == jmpdeferPC {
...@@ -920,14 +922,20 @@ func tracebackHexdump(stk stack, frame *stkframe, bad uintptr) { ...@@ -920,14 +922,20 @@ func tracebackHexdump(stk stack, frame *stkframe, bad uintptr) {
} }
// Does f mark the top of a goroutine stack? // Does f mark the top of a goroutine stack?
func topofstack(f funcInfo) bool { func topofstack(f funcInfo, g0 bool) bool {
pc := f.entry pc := f.entry
return pc == goexitPC || return pc == goexitPC ||
pc == mstartPC || pc == mstartPC ||
pc == mcallPC || pc == mcallPC ||
pc == morestackPC || pc == morestackPC ||
pc == rt0_goPC || 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 // isSystemGoroutine reports whether the goroutine g must be omitted in
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment