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