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 <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Austin Clements 2015-11-23 15:13:16 -05:00
parent 22a204dd0f
commit 50d8d4e834

View file

@ -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)
}