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

     1  // Copyright 2010 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  package runtime
     6  
     7  import "unsafe"
     8  
     9  // May run during STW, so write barriers are not allowed.
    10  //go:nowritebarrier
    11  func sighandler(_ureg *ureg, note *byte, gp *g) int {
    12  	_g_ := getg()
    13  	var t sigTabT
    14  	var docrash bool
    15  	var sig int
    16  	var flags int
    17  	var level int32
    18  
    19  	c := &sigctxt{_ureg}
    20  	notestr := gostringnocopy(note)
    21  
    22  	// The kernel will never pass us a nil note or ureg so we probably
    23  	// made a mistake somewhere in sigtramp.
    24  	if _ureg == nil || note == nil {
    25  		print("sighandler: ureg ", _ureg, " note ", note, "\n")
    26  		goto Throw
    27  	}
    28  	// Check that the note is no more than ERRMAX bytes (including
    29  	// the trailing NUL). We should never receive a longer note.
    30  	if len(notestr) > _ERRMAX-1 {
    31  		print("sighandler: note is longer than ERRMAX\n")
    32  		goto Throw
    33  	}
    34  	// See if the note matches one of the patterns in sigtab.
    35  	// Notes that do not match any pattern can be handled at a higher
    36  	// level by the program but will otherwise be ignored.
    37  	flags = _SigNotify
    38  	for sig, t = range sigtable {
    39  		if hasprefix(notestr, t.name) {
    40  			flags = t.flags
    41  			break
    42  		}
    43  	}
    44  	if flags&_SigGoExit != 0 {
    45  		exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix.
    46  	}
    47  	if flags&_SigPanic != 0 {
    48  		// Copy the error string from sigtramp's stack into m->notesig so
    49  		// we can reliably access it from the panic routines.
    50  		memmove(unsafe.Pointer(_g_.m.notesig), unsafe.Pointer(note), uintptr(len(notestr)+1))
    51  		gp.sig = uint32(sig)
    52  		gp.sigpc = c.pc()
    53  
    54  		pc := uintptr(c.pc())
    55  		sp := uintptr(c.sp())
    56  
    57  		// If we don't recognize the PC as code
    58  		// but we do recognize the top pointer on the stack as code,
    59  		// then assume this was a call to non-code and treat like
    60  		// pc == 0, to make unwinding show the context.
    61  		if pc != 0 && findfunc(pc) == nil && findfunc(*(*uintptr)(unsafe.Pointer(sp))) != nil {
    62  			pc = 0
    63  		}
    64  
    65  		// Only push sigpanic if PC != 0.
    66  		//
    67  		// If PC == 0, probably panicked because of a call to a nil func.
    68  		// Not pushing that onto SP will make the trace look like a call
    69  		// to sigpanic instead. (Otherwise the trace will end at
    70  		// sigpanic and we won't get to see who faulted).
    71  		if pc != 0 {
    72  			if regSize > ptrSize {
    73  				sp -= ptrSize
    74  				*(*uintptr)(unsafe.Pointer(sp)) = 0
    75  			}
    76  			sp -= ptrSize
    77  			*(*uintptr)(unsafe.Pointer(sp)) = pc
    78  			c.setsp(sp)
    79  		}
    80  		c.setpc(funcPC(sigpanic))
    81  		return _NCONT
    82  	}
    83  	if flags&_SigNotify != 0 {
    84  		if sendNote(note) {
    85  			return _NCONT
    86  		}
    87  	}
    88  	if flags&_SigKill != 0 {
    89  		goto Exit
    90  	}
    91  	if flags&_SigThrow == 0 {
    92  		return _NCONT
    93  	}
    94  Throw:
    95  	_g_.m.throwing = 1
    96  	_g_.m.caughtsig.set(gp)
    97  	startpanic()
    98  	print(notestr, "\n")
    99  	print("PC=", hex(c.pc()), "\n")
   100  	print("\n")
   101  	level, _, docrash = gotraceback()
   102  	if level > 0 {
   103  		goroutineheader(gp)
   104  		tracebacktrap(c.pc(), c.sp(), 0, gp)
   105  		tracebackothers(gp)
   106  		print("\n")
   107  		dumpregs(_ureg)
   108  	}
   109  	if docrash {
   110  		crash()
   111  	}
   112  Exit:
   113  	goexitsall(note)
   114  	exits(note)
   115  	return _NDFLT // not reached
   116  }
   117  
   118  func sigenable(sig uint32) {
   119  }
   120  
   121  func sigdisable(sig uint32) {
   122  }
   123  
   124  func sigignore(sig uint32) {
   125  }
   126  
   127  func resetcpuprofiler(hz int32) {
   128  	// TODO: Enable profiling interrupts.
   129  	getg().m.profilehz = hz
   130  }