From 50d8d4e834039574602df287522a25bb70c101bb Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Mon, 23 Nov 2015 15:13:16 -0500 Subject: [PATCH] runtime: simplify sigprof traceback interlocking The addition of stack barrier locking to copystack subsumes the partial fix from commit bbd1a1c for SIGPROF during copystack. With the stack barrier locking, this commit simplifies the rule in sigprof to: the user stack can be traced only if sigprof can acquire the stack barrier lock. Updates #12932, #13362. Change-Id: I1c1f80015053d0ac7761e9e0c7437c2aba26663f Reviewed-on: https://go-review.googlesource.com/17192 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Russ Cox --- src/runtime/proc.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/runtime/proc.go b/src/runtime/proc.go index c0df6f1d05..ade4d11433 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -2978,18 +2978,25 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) { // To recap, there are no constraints on the assembly being used for the // transition. We simply require that g and SP match and that the PC is not // in gogo. - traceback := true + traceback, tracebackUser := true, true haveStackLock := false if gp == nil || sp < gp.stack.lo || gp.stack.hi < sp || setsSP(pc) { traceback = false } else if gp.m.curg != nil { + // The user stack is safe to scan only if we can + // acquire the stack barrier lock. if gcTryLockStackBarriers(gp.m.curg) { haveStackLock = true } else { // Stack barriers are being inserted or // removed, so we can't get a consistent - // traceback right now. - traceback = false + // traceback of the user stack right now. + tracebackUser = false + if gp == gp.m.curg { + // We're on the user stack, so don't + // do any traceback. + traceback = false + } } } var stk [maxCPUProfStack]uintptr @@ -3000,12 +3007,9 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) { // This is especially important on windows, since all syscalls are cgo calls. n = gentraceback(mp.curg.syscallpc, mp.curg.syscallsp, 0, mp.curg, 0, &stk[0], len(stk), nil, nil, 0) } else if traceback { - flags := uint(_TraceTrap | _TraceJumpStack) - if gp.m.curg != nil && readgstatus(gp.m.curg) == _Gcopystack { - // We can traceback the system stack, but - // don't jump to the potentially inconsistent - // user stack. - flags &^= _TraceJumpStack + var flags uint = _TraceTrap + if tracebackUser { + flags |= _TraceJumpStack } n = gentraceback(pc, sp, lr, gp, 0, &stk[0], len(stk), nil, nil, flags) } -- 2.50.0