aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2022-09-30 19:01:09 -0400
committerMichael Knyszek <mknyszek@google.com>2022-11-09 18:44:47 +0000
commita3dce1276887df0de970cac8524b822c092ab39f (patch)
treeeeb9ea57fa832d6c3a45e06495e44b9afd363265
parentd2a7a180d38d4a51eb5d8f86bb71bed0ecee09ce (diff)
downloadgo-a3dce1276887df0de970cac8524b822c092ab39f.tar.gz
go-a3dce1276887df0de970cac8524b822c092ab39f.zip
[release-branch.go1.18] runtime: don't jump stack if at entry of systemstack
The traceback code has special "jump stack" logic, to trace back stack switches through systemstack. If we're at the entry of systemstack, the stack switch hasn't happened, so don't jump to user stack. The jump stack logic is only used if we're on the g0 stack. It can happen that we're at the entry of a recursive systemstack call on the g0 stack. In we jump stack here, there will be two problems: 1. There are frames between entering the g0 stack and this recursive systemstack call. Those frames will be lost. 2. Worse, we switched frame.sp but frame.fp calculation will use the entry SP delta (0), which will be wrong, which in turn leads wrong frame.lr and things will go off. For now, don't jump stack if we're at entry of systemstack (SP delta is 0). Using a per-PC SPWRITE marker may be a better fix. If we haven't written the SP, we haven't switched the stack so we can just unwind like a normal function. Updates #55851. Fixes #56635. Change-Id: I2b624c8c086b235b34d9c7d3cebd4a37264f00f8 Reviewed-on: https://go-review.googlesource.com/c/go/+/437299 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Cherry Mui <cherryyz@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> (cherry picked from commit 500bc6b8056ee2eaf7640610a48ffa00bdd896a5) Reviewed-on: https://go-review.googlesource.com/c/go/+/448517
-rw-r--r--src/runtime/traceback.go11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index 56128dc882..b8f580f084 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -182,6 +182,17 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
case funcID_systemstack:
// systemstack returns normally, so just follow the
// stack transition.
+ if usesLR && funcspdelta(f, frame.pc, &cache) == 0 {
+ // We're at the function prologue and the stack
+ // switch hasn't happened, or epilogue where we're
+ // about to return. Just unwind normally.
+ // Do this only on LR machines because on x86
+ // systemstack doesn't have an SP delta (the CALL
+ // instruction opens the frame), therefore no way
+ // to check.
+ flag &^= funcFlag_SPWRITE
+ break
+ }
frame.sp = gp.m.curg.sched.sp
stack = gp.m.curg.stack
cgoCtxt = gp.m.curg.cgoCtxt