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