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