runtime: account for missing frame pointer in preamble

If a goroutine is synchronously preempted, then taking a
frame-pointer-based stack trace at that preemption will skip PC of the
caller of the function which called into morestack. This happens because
the frame pointer is pushed to the stack after the preamble, leaving the
stack in an odd state for frame pointer unwinding.

Deal with this by marking a goroutine as synchronously preempted and
using that signal to load the missing PC from the stack. On LR platforms
this is available in gp.sched.lr. On non-LR platforms like x86, it's at
gp.sched.sp, because there are no args, no locals, and no frame pointer
pushed to the SP yet.

For #68090.

Change-Id: I73a1206d8b84eecb8a96dbe727195da30088f288
Reviewed-on: https://go-review.googlesource.com/c/go/+/684435
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nick Ripley <nick.ripley@datadoghq.com>
This commit is contained in:
Michael Anthony Knyszek 2025-06-27 00:59:49 +00:00 committed by Michael Knyszek
parent fdc076ce76
commit 742fda9524
7 changed files with 47 additions and 9 deletions

View file

@ -1115,6 +1115,9 @@ func newstack() {
shrinkstack(gp)
}
// Set a flag indicated that we've been synchronously preempted.
gp.syncSafePoint = true
if gp.preemptStop {
preemptPark(gp) // never returns
}