Skip to content

Commit 9c1d19a

Browse files
prattmicgopherbot
authored andcommitted
runtime: clear frame pointer in mcall
On amd64, mcall leaves BP untouched, so the callback will push BP, connecting the g0 stack to the calling g stack. This seems OK (frame pointer unwinders like Linux perf can see what user code called into the scheduler), but the "scheduler" part is problematic. mcall is used when calling into the scheduler to deschedule the current goroutine (e.g., in goyield). Once the goroutine is descheduled, it may be picked up by another M and continue execution. The other thread is mutating the goroutine stack, but our M still has a frame pointer pointing to the goroutine stack. A frame pointer unwinder like Linux perf could get bogus values off of the mutating stack. Note that though the execution tracer uses framepointer unwinding, it never unwinds a g0, so it isn't affected. Clear the frame pointer in mcall so that unwinding always stops at mcall. On arm64, mcall stores the frame pointer from g0.sched.bp. This doesn't really make any sense. mcall wasn't called by whatever used g0 last, so at best unwinding will get misleading results (e.g., it might look like cgocallback calls mcall?). Also clear the frame pointer on arm64. Other architectures don't use frame pointers. For #63630. Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest,gotip-linux-arm64-longtest Change-Id: I6a6a636cb6404f3c95ecabdb969c9b8184615cee Reviewed-on: https://go-review.googlesource.com/c/go/+/669615 Reviewed-by: Michael Knyszek <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Nick Ripley <[email protected]> Reviewed-by: Cherry Mui <[email protected]> Auto-Submit: Michael Pratt <[email protected]>
1 parent 21908c3 commit 9c1d19a

File tree

2 files changed

+2
-1
lines changed

2 files changed

+2
-1
lines changed

src/runtime/asm_amd64.s

+1
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ goodm:
452452
get_tls(CX) // Set G in TLS
453453
MOVQ R14, g(CX)
454454
MOVQ (g_sched+gobuf_sp)(R14), SP // sp = g0.sched.sp
455+
MOVQ $0, BP // clear frame pointer, as caller may execute on another M
455456
PUSHQ AX // open up space for fn's arg spill slot
456457
MOVQ 0(DX), R12
457458
CALL R12 // fn(g)

src/runtime/asm_arm64.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
233233

234234
MOVD (g_sched+gobuf_sp)(g), R0
235235
MOVD R0, RSP // sp = m->g0->sched.sp
236-
MOVD (g_sched+gobuf_bp)(g), R29
236+
MOVD $0, R29 // clear frame pointer, as caller may execute on another M
237237
MOVD R3, R0 // arg = g
238238
MOVD $0, -16(RSP) // dummy LR
239239
SUB $16, RSP

0 commit comments

Comments
 (0)