aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Ripley <nick.ripley@datadoghq.com>2025-11-17 11:47:20 -0500
committerGopher Robot <gobot@golang.org>2025-11-17 12:06:42 -0800
commiteda2e8c683798e435e725f60f0bb580eb4aa9686 (patch)
tree460989b26f694b04498d85b766c91fce77d81f88 /src
parent6919858338ae3c4f244f65ca87e9e71662a83413 (diff)
downloadgo-eda2e8c683798e435e725f60f0bb580eb4aa9686.tar.xz
runtime: clear frame pointer at thread entry points
There are a few places in the runtime where new threads enter Go code with a possibly invalid frame pointer. mstart is the entry point for new Ms, and rt0_go is the entrypoint for the program. As we try to introduce frame pointer unwinding in more places (e.g. for heap profiling in CL 540476 or for execution trace events on the system stack in CL 593835), we see these functions on the stack. We need to ensure that they have valid frame pointers. These functions are both considered the "top" (first) frame frame of the call stack, so this CL sets the frame pointer register to 0 in these functions. Updates #63630 Change-Id: I6a6a6964a9ebc6f68ba23d2616e5fb6f19677f97 Reviewed-on: https://go-review.googlesource.com/c/go/+/721020 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/runtime/asm_amd64.s15
-rw-r--r--src/runtime/asm_arm64.s15
2 files changed, 30 insertions, 0 deletions
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index a4c6c53a90..f4244f6e06 100644
--- a/src/runtime/asm_amd64.s
+++ b/src/runtime/asm_amd64.s
@@ -181,6 +181,14 @@ TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
MOVQ AX, 24(SP)
MOVQ BX, 32(SP)
+ // This is typically the entry point for Go programs.
+ // Call stack unwinding must not proceed past this frame.
+ // Set the frame pointer register to 0 so that frame pointer-based unwinders
+ // (which don't use debug info for performance reasons)
+ // won't attempt to unwind past this function.
+ // See go.dev/issue/63630
+ MOVQ $0, BP
+
// create istack out of the given (operating system) stack.
// _cgo_init may update stackguard.
MOVQ $runtime·g0(SB), DI
@@ -408,6 +416,13 @@ TEXT runtime·asminit(SB),NOSPLIT,$0-0
RET
TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME|NOFRAME,$0
+ // This is the root frame of new Go-created OS threads.
+ // Call stack unwinding must not proceed past this frame.
+ // Set the frame pointer register to 0 so that frame pointer-based unwinders
+ // (which don't use debug info for performance reasons)
+ // won't attempt to unwind past this function.
+ // See go.dev/issue/63630
+ MOVD $0, BP
CALL runtime·mstart0(SB)
RET // not reached
diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s
index 902a7066aa..01f2690f4e 100644
--- a/src/runtime/asm_arm64.s
+++ b/src/runtime/asm_arm64.s
@@ -109,6 +109,14 @@ TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
MOVW R0, 8(RSP) // argc
MOVD R1, 16(RSP) // argv
+ // This is typically the entry point for Go programs.
+ // Call stack unwinding must not proceed past this frame.
+ // Set the frame pointer register to 0 so that frame pointer-based unwinders
+ // (which don't use debug info for performance reasons)
+ // won't attempt to unwind past this function.
+ // See go.dev/issue/63630
+ MOVD $0, R29
+
#ifdef TLS_darwin
// Initialize TLS.
MOVD ZR, g // clear g, make sure it's not junk.
@@ -248,6 +256,13 @@ TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
RET
TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+ // This is the root frame of new Go-created OS threads.
+ // Call stack unwinding must not proceed past this frame.
+ // Set the frame pointer register to 0 so that frame pointer-based unwinders
+ // (which don't use debug info for performance reasons)
+ // won't attempt to unwind past this function.
+ // See go.dev/issue/63630
+ MOVD $0, R29
BL runtime·mstart0(SB)
RET // not reached