github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/src/runtime/signal_ppc64x.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build linux
     6  // +build ppc64 ppc64le
     7  
     8  package runtime
     9  
    10  import "unsafe"
    11  
    12  func dumpregs(c *sigctxt) {
    13  	print("r0   ", hex(c.r0()), "\t")
    14  	print("r1   ", hex(c.r1()), "\n")
    15  	print("r2   ", hex(c.r2()), "\t")
    16  	print("r3   ", hex(c.r3()), "\n")
    17  	print("r4   ", hex(c.r4()), "\t")
    18  	print("r5   ", hex(c.r5()), "\n")
    19  	print("r6   ", hex(c.r6()), "\t")
    20  	print("r7   ", hex(c.r7()), "\n")
    21  	print("r8   ", hex(c.r8()), "\t")
    22  	print("r9   ", hex(c.r9()), "\n")
    23  	print("r10  ", hex(c.r10()), "\t")
    24  	print("r11  ", hex(c.r11()), "\n")
    25  	print("r12  ", hex(c.r12()), "\t")
    26  	print("r13  ", hex(c.r13()), "\n")
    27  	print("r14  ", hex(c.r14()), "\t")
    28  	print("r15  ", hex(c.r15()), "\n")
    29  	print("r16  ", hex(c.r16()), "\t")
    30  	print("r17  ", hex(c.r17()), "\n")
    31  	print("r18  ", hex(c.r18()), "\t")
    32  	print("r19  ", hex(c.r19()), "\n")
    33  	print("r20  ", hex(c.r20()), "\t")
    34  	print("r21  ", hex(c.r21()), "\n")
    35  	print("r22  ", hex(c.r22()), "\t")
    36  	print("r23  ", hex(c.r23()), "\n")
    37  	print("r24  ", hex(c.r24()), "\t")
    38  	print("r25  ", hex(c.r25()), "\n")
    39  	print("r26  ", hex(c.r26()), "\t")
    40  	print("r27  ", hex(c.r27()), "\n")
    41  	print("r28  ", hex(c.r28()), "\t")
    42  	print("r29  ", hex(c.r29()), "\n")
    43  	print("r30  ", hex(c.r30()), "\t")
    44  	print("r31  ", hex(c.r31()), "\n")
    45  	print("pc   ", hex(c.pc()), "\t")
    46  	print("ctr  ", hex(c.ctr()), "\n")
    47  	print("link ", hex(c.link()), "\t")
    48  	print("xer  ", hex(c.xer()), "\n")
    49  	print("ccr  ", hex(c.ccr()), "\t")
    50  	print("trap ", hex(c.trap()), "\n")
    51  }
    52  
    53  var crashing int32
    54  
    55  // May run during STW, so write barriers are not allowed.
    56  //go:nowritebarrier
    57  func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
    58  	_g_ := getg()
    59  	c := &sigctxt{info, ctxt}
    60  
    61  	if sig == _SIGPROF {
    62  		sigprof(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.link()), gp, _g_.m)
    63  		return
    64  	}
    65  	flags := int32(_SigThrow)
    66  	if sig < uint32(len(sigtable)) {
    67  		flags = sigtable[sig].flags
    68  	}
    69  	if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
    70  		// Make it look like a call to the signal func.
    71  		// Have to pass arguments out of band since
    72  		// augmenting the stack frame would break
    73  		// the unwinding code.
    74  		gp.sig = sig
    75  		gp.sigcode0 = uintptr(c.sigcode())
    76  		gp.sigcode1 = uintptr(c.fault())
    77  		gp.sigpc = uintptr(c.pc())
    78  
    79  		// We arrange link, and pc to pretend the panicking
    80  		// function calls sigpanic directly.
    81  		// Always save LINK to stack so that panics in leaf
    82  		// functions are correctly handled. This smashes
    83  		// the stack frame but we're not going back there
    84  		// anyway.
    85  		sp := c.sp() - minFrameSize
    86  		c.set_sp(sp)
    87  		*(*uint64)(unsafe.Pointer(uintptr(sp))) = c.link()
    88  
    89  		pc := uintptr(gp.sigpc)
    90  
    91  		// If we don't recognize the PC as code
    92  		// but we do recognize the link register as code,
    93  		// then assume this was a call to non-code and treat like
    94  		// pc == 0, to make unwinding show the context.
    95  		if pc != 0 && findfunc(pc) == nil && findfunc(uintptr(c.link())) != nil {
    96  			pc = 0
    97  		}
    98  
    99  		// Don't bother saving PC if it's zero, which is
   100  		// probably a call to a nil func: the old link register
   101  		// is more useful in the stack trace.
   102  		if pc != 0 {
   103  			c.set_link(uint64(pc))
   104  		}
   105  
   106  		// In case we are panicking from external C code
   107  		c.set_r0(0)
   108  		c.set_r30(uint64(uintptr(unsafe.Pointer(gp))))
   109  		c.set_pc(uint64(funcPC(sigpanic)))
   110  		return
   111  	}
   112  
   113  	if c.sigcode() == _SI_USER || flags&_SigNotify != 0 {
   114  		if sigsend(sig) {
   115  			return
   116  		}
   117  	}
   118  
   119  	if flags&_SigKill != 0 {
   120  		exit(2)
   121  	}
   122  
   123  	if flags&_SigThrow == 0 {
   124  		return
   125  	}
   126  
   127  	_g_.m.throwing = 1
   128  	_g_.m.caughtsig.set(gp)
   129  
   130  	if crashing == 0 {
   131  		startpanic()
   132  	}
   133  
   134  	if sig < uint32(len(sigtable)) {
   135  		print(sigtable[sig].name, "\n")
   136  	} else {
   137  		print("Signal ", sig, "\n")
   138  	}
   139  
   140  	print("PC=", hex(c.pc()), " m=", _g_.m.id, "\n")
   141  	if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
   142  		print("signal arrived during cgo execution\n")
   143  		gp = _g_.m.lockedg
   144  	}
   145  	print("\n")
   146  
   147  	level, _, docrash := gotraceback()
   148  	if level > 0 {
   149  		goroutineheader(gp)
   150  		tracebacktrap(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.link()), gp)
   151  		if crashing > 0 && gp != _g_.m.curg && _g_.m.curg != nil && readgstatus(_g_.m.curg)&^_Gscan == _Grunning {
   152  			// tracebackothers on original m skipped this one; trace it now.
   153  			goroutineheader(_g_.m.curg)
   154  			traceback(^uintptr(0), ^uintptr(0), 0, gp)
   155  		} else if crashing == 0 {
   156  			tracebackothers(gp)
   157  			print("\n")
   158  		}
   159  		dumpregs(c)
   160  	}
   161  
   162  	if docrash {
   163  		crashing++
   164  		if crashing < sched.mcount {
   165  			// There are other m's that need to dump their stacks.
   166  			// Relay SIGQUIT to the next m by sending it to the current process.
   167  			// All m's that have already received SIGQUIT have signal masks blocking
   168  			// receipt of any signals, so the SIGQUIT will go to an m that hasn't seen it yet.
   169  			// When the last m receives the SIGQUIT, it will fall through to the call to
   170  			// crash below. Just in case the relaying gets botched, each m involved in
   171  			// the relay sleeps for 5 seconds and then does the crash/exit itself.
   172  			// In expected operation, the last m has received the SIGQUIT and run
   173  			// crash/exit and the process is gone, all long before any of the
   174  			// 5-second sleeps have finished.
   175  			print("\n-----\n\n")
   176  			raiseproc(_SIGQUIT)
   177  			usleep(5 * 1000 * 1000)
   178  		}
   179  		crash()
   180  	}
   181  
   182  	exit(2)
   183  }