mirror of
https://github.com/golang/go
synced 2024-11-12 05:30:21 -07:00
runtime: update SP when jumping stacks in traceback
When gentraceback starts on a system stack in sigprof, it is configured to jump to the user stack when it reaches the end of the system stack. Currently this updates the current frame's FP, but not its SP. This is okay on non-LR machines (x86) because frame.sp is only used to find defers, which the bottom-most frame of the user stack will never have. However, on LR machines, we use frame.sp to find the saved LR. We then use to resolve the function of the next frame, which is used to resolved the size of the next frame. Since we're not updating frame.sp on a stack jump, we read the saved LR from the system stack instead of the user stack and wind up resolving the wrong function and hence the wrong frame size for the next frame. This has had remarkably few ill effects (though the resulting profiles must be wrong). We noticed it because of a bad interaction with stack barriers. Specifically, once we get the next frame size wrong, we also get the location of its LR wrong. If we happen to get a stack slot that contains a stale stack barrier LR (for a stack barrier we already hit) and hasn't been overwritten with something else as we re-grew the stack, gentraceback will fail with a "found next stack barrier at ..." error, pointing at the slot that it thinks is an LR, but isn't. Fixes #15138. Updates #15313 (might fix it). Change-Id: I13cfa322b44c0c2f23ac2b3d03e12631e4a6406b Reviewed-on: https://go-review.googlesource.com/23291 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
7b6b5e3404
commit
a640d95172
@ -256,6 +256,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
|
||||
sp := frame.sp
|
||||
if flags&_TraceJumpStack != 0 && f.entry == systemstackPC && gp == g.m.g0 && gp.m.curg != nil {
|
||||
sp = gp.m.curg.sched.sp
|
||||
frame.sp = sp
|
||||
stkbarG = gp.m.curg
|
||||
stkbar = stkbarG.stkbar[stkbarG.stkbarPos:]
|
||||
cgoCtxt = gp.m.curg.cgoCtxt
|
||||
|
Loading…
Reference in New Issue
Block a user