aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/runtime2.go
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2024-04-18 20:54:55 +0000
committerMichael Knyszek <mknyszek@google.com>2024-04-19 17:25:00 +0000
commit2b82a4f488179a62a69dd318ea62f0624641ae63 (patch)
treee86da95881d3bd61e9e6f9065b4ca658f4974487 /src/runtime/runtime2.go
parentdcb5de5cac5baee703b1fe215f28f22aebc93437 (diff)
downloadgo-2b82a4f488179a62a69dd318ea62f0624641ae63.tar.xz
runtime: track frame pointer while in syscall
Currently the runtime only tracks the PC and SP upon entering a syscall, but not the FP (BP). This is mainly for historical reasons, and because the tracer (which uses the frame pointer unwinder) does not need it. Until it did, of course, in CL 567076, where the tracer tries to take a stack trace of a goroutine that's in a syscall from afar. It tries to use gp.sched.bp and lots of things go wrong. It *really* should be using the equivalent of gp.syscallbp, which doesn't exist before this CL. This change introduces gp.syscallbp and tracks it. It also introduces getcallerfp which is nice for simplifying some code. Because we now have gp.syscallbp, we can also delete the frame skip count computation in traceLocker.GoSysCall, because it's now the same regardless of whether frame pointer unwinding is used. Fixes #66889. Change-Id: Ib6d761c9566055e0a037134138cb0f81be73ecf7 Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-nocgo Reviewed-on: https://go-review.googlesource.com/c/go/+/580255 Auto-Submit: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/runtime/runtime2.go')
-rw-r--r--src/runtime/runtime2.go15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 83252abb44..b58255f279 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -437,6 +437,7 @@ type g struct {
sched gobuf
syscallsp uintptr // if status==Gsyscall, syscallsp = sched.sp to use during gc
syscallpc uintptr // if status==Gsyscall, syscallpc = sched.pc to use during gc
+ syscallbp uintptr // if status==Gsyscall, syscallbp = sched.bp to use in fpTraceback
stktopsp uintptr // expected sp at top of stack, to check in traceback
// param is a generic pointer parameter field used to pass
// values in particular contexts where other storage for the
@@ -1263,3 +1264,17 @@ var (
// Must agree with internal/buildcfg.FramePointerEnabled.
const framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64"
+
+// getcallerfp returns the frame pointer of the caller of the caller
+// of this function.
+//
+//go:nosplit
+//go:noinline
+func getcallerfp() uintptr {
+ fp := getfp() // This frame's FP.
+ if fp != 0 {
+ fp = *(*uintptr)(unsafe.Pointer(fp)) // The caller's FP.
+ fp = *(*uintptr)(unsafe.Pointer(fp)) // The caller's caller's FP.
+ }
+ return fp
+}