]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: simplify sigprof traceback interlocking
authorAustin Clements <austin@google.com>
Mon, 23 Nov 2015 20:13:16 +0000 (15:13 -0500)
committerAustin Clements <austin@google.com>
Tue, 15 Dec 2015 20:12:17 +0000 (20:12 +0000)
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>
src/runtime/proc.go

index c0df6f1d05f6c456b8493d24e1549f84880a1321..ade4d1143334c3fa2c3a26295e2b1f61cbc8973b 100644 (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)
        }