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