components/golang/patches/0046-release-branch.go1.5-runtime-handle-sigprof-in-stack.patch
changeset 5331 9c955076ffe3
equal deleted inserted replaced
5330:c36e3195e3e9 5331:9c955076ffe3
       
     1 From 2a6c7739b5bdb5fbaf743d89a18bd466fb178fe1 Mon Sep 17 00:00:00 2001
       
     2 From: Austin Clements <[email protected]>
       
     3 Date: Wed, 18 Nov 2015 13:20:35 -0500
       
     4 Subject: [PATCH 46/63] [release-branch.go1.5] runtime: handle sigprof in
       
     5  stackBarrier
       
     6 
       
     7 Currently, if a profiling signal happens in the middle of
       
     8 stackBarrier, gentraceback may see inconsistencies between stkbar and
       
     9 the barriers on the stack and it will certainly get the wrong return
       
    10 PC for stackBarrier. In most cases, the return PC won't be a PC at all
       
    11 and this will immediately abort the traceback (which is considered
       
    12 okay for a sigprof), but if it happens to be a valid PC this may sent
       
    13 gentraceback down a rabbit hole.
       
    14 
       
    15 Fix this by detecting when the gentraceback starts in stackBarrier and
       
    16 simulating the completion of the barrier to get the correct initial
       
    17 frame.
       
    18 
       
    19 Change-Id: Ib11f705ac9194925f63fe5dfbfc84013a38333e6
       
    20 Reviewed-on: https://go-review.googlesource.com/17035
       
    21 Reviewed-by: Russ Cox <[email protected]>
       
    22 Run-TryBot: Austin Clements <[email protected]>
       
    23 TryBot-Result: Gobot Gobot <[email protected]>
       
    24 Reviewed-on: https://go-review.googlesource.com/17056
       
    25 ---
       
    26  src/runtime/traceback.go | 28 ++++++++++++++++++++++++++++
       
    27  1 file changed, 28 insertions(+)
       
    28 
       
    29 diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
       
    30 index 2def359..aed6cbd 100644
       
    31 --- a/src/runtime/traceback.go
       
    32 +++ b/src/runtime/traceback.go
       
    33 @@ -188,6 +188,34 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
       
    34  	}
       
    35  
       
    36  	f := findfunc(frame.pc)
       
    37 +	if f.entry == stackBarrierPC {
       
    38 +		// We got caught in the middle of a stack barrier
       
    39 +		// (presumably by a signal), so stkbar may be
       
    40 +		// inconsistent with the barriers on the stack.
       
    41 +		// Simulate the completion of the barrier.
       
    42 +		//
       
    43 +		// On x86, SP will be exactly one word above
       
    44 +		// savedLRPtr. On LR machines, SP will be above
       
    45 +		// savedLRPtr by some frame size.
       
    46 +		var stkbarPos uintptr
       
    47 +		if len(stkbar) > 0 && stkbar[0].savedLRPtr < sp0 {
       
    48 +			// stackBarrier has not incremented stkbarPos.
       
    49 +			stkbarPos = gp.stkbarPos
       
    50 +		} else if gp.stkbarPos > 0 && gp.stkbar[gp.stkbarPos-1].savedLRPtr < sp0 {
       
    51 +			// stackBarrier has incremented stkbarPos.
       
    52 +			stkbarPos = gp.stkbarPos - 1
       
    53 +		} else {
       
    54 +			printlock()
       
    55 +			print("runtime: failed to unwind through stackBarrier at SP ", hex(sp0), " index ", gp.stkbarPos, "; ")
       
    56 +			gcPrintStkbars(gp.stkbar)
       
    57 +			print("\n")
       
    58 +			throw("inconsistent state in stackBarrier")
       
    59 +		}
       
    60 +
       
    61 +		frame.pc = gp.stkbar[stkbarPos].savedLRVal
       
    62 +		stkbar = gp.stkbar[stkbarPos+1:]
       
    63 +		f = findfunc(frame.pc)
       
    64 +	}
       
    65  	if f == nil {
       
    66  		if callback != nil {
       
    67  			print("runtime: unknown pc ", hex(frame.pc), "\n")
       
    68 -- 
       
    69 2.6.1
       
    70