components/golang/patches/0042-release-branch.go1.5-runtime-make-SIGPROF-skip-stack.patch
changeset 5331 9c955076ffe3
equal deleted inserted replaced
5330:c36e3195e3e9 5331:9c955076ffe3
       
     1 From a8e839bb55bdba131d5c2f72d6bb49130fac55e3 Mon Sep 17 00:00:00 2001
       
     2 From: Austin Clements <[email protected]>
       
     3 Date: Wed, 11 Nov 2015 15:34:54 -0500
       
     4 Subject: [PATCH 42/63] [release-branch.go1.5] runtime: make SIGPROF skip
       
     5  stacks that are being copied
       
     6 
       
     7 sigprof tracebacks the stack across systemstack switches to make
       
     8 profile tracebacks more complete. However, it does this even if the
       
     9 user stack is currently being copied, which means it may be in an
       
    10 inconsistent state that will cause the traceback to panic.
       
    11 
       
    12 One specific way this can happen is during stack shrinking. Some
       
    13 goroutine blocks for STW, then enters gchelper, which then assists
       
    14 with root marking. If that root marking happens to pick the original
       
    15 goroutine and its stack needs to be shrunk, it will begin to copy that
       
    16 stack. During this copy, the stack is generally inconsistent and, in
       
    17 particular, the actual locations of the stack barriers and their
       
    18 recorded locations are temporarily out of sync. If a SIGPROF happens
       
    19 during this inconsistency, it will walk the stack all the way back to
       
    20 the blocked goroutine and panic when it fails to unwind the stack
       
    21 barriers.
       
    22 
       
    23 Fix this by disallowing jumping to the user stack during SIGPROF if
       
    24 that user stack is in the process of being copied.
       
    25 
       
    26 Fixes #12932.
       
    27 
       
    28 Change-Id: I9ef694c2c01e3653e292ce22612418dd3daff1b4
       
    29 Reviewed-on: https://go-review.googlesource.com/16819
       
    30 Reviewed-by: Daniel Morsing <[email protected]>
       
    31 Run-TryBot: Austin Clements <[email protected]>
       
    32 TryBot-Result: Gobot Gobot <[email protected]>
       
    33 Reviewed-on: https://go-review.googlesource.com/16985
       
    34 Reviewed-by: Ian Lance Taylor <[email protected]>
       
    35 Reviewed-by: Russ Cox <[email protected]>
       
    36 ---
       
    37  src/runtime/proc1.go | 9 ++++++++-
       
    38  1 file changed, 8 insertions(+), 1 deletion(-)
       
    39 
       
    40 diff --git a/src/runtime/proc1.go b/src/runtime/proc1.go
       
    41 index 09cb775..55f1a24 100644
       
    42 --- a/src/runtime/proc1.go
       
    43 +++ b/src/runtime/proc1.go
       
    44 @@ -2582,7 +2582,14 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
       
    45  		// This is especially important on windows, since all syscalls are cgo calls.
       
    46  		n = gentraceback(mp.curg.syscallpc, mp.curg.syscallsp, 0, mp.curg, 0, &stk[0], len(stk), nil, nil, 0)
       
    47  	} else if traceback {
       
    48 -		n = gentraceback(pc, sp, lr, gp, 0, &stk[0], len(stk), nil, nil, _TraceTrap|_TraceJumpStack)
       
    49 +		flags := uint(_TraceTrap | _TraceJumpStack)
       
    50 +		if gp.m.curg != nil && readgstatus(gp.m.curg) == _Gcopystack {
       
    51 +			// We can traceback the system stack, but
       
    52 +			// don't jump to the potentially inconsistent
       
    53 +			// user stack.
       
    54 +			flags &^= _TraceJumpStack
       
    55 +		}
       
    56 +		n = gentraceback(pc, sp, lr, gp, 0, &stk[0], len(stk), nil, nil, flags)
       
    57  	}
       
    58  	if !traceback || n <= 0 {
       
    59  		// Normal traceback is impossible or has failed.
       
    60 -- 
       
    61 2.6.1
       
    62