mirror of
https://github.com/golang/go.git
synced 2025-05-30 19:52:53 +00:00
runtime: consolidate arch-specific signal handlers on Plan 9
Change-Id: I4379418853c523fc9aaeb5d6f37bc96117841418 Reviewed-on: https://go-review.googlesource.com/1786 Reviewed-by: David du Colombier <0intro@gmail.com> Reviewed-by: Aram Hăvărneanu <aram@mgk.ro>
This commit is contained in:
parent
f3de21767e
commit
3d032d7653
@ -23,3 +23,29 @@ type ureg struct {
|
|||||||
sp uint32
|
sp uint32
|
||||||
ss uint32 /* old stack segment */
|
ss uint32 /* old stack segment */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type sigctxt struct {
|
||||||
|
u *ureg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *sigctxt) pc() uintptr { return uintptr(c.u.pc) }
|
||||||
|
func (c *sigctxt) sp() uintptr { return uintptr(c.u.sp) }
|
||||||
|
|
||||||
|
func (c *sigctxt) setpc(x uintptr) { c.u.pc = uint32(x) }
|
||||||
|
func (c *sigctxt) setsp(x uintptr) { c.u.sp = uint32(x) }
|
||||||
|
|
||||||
|
func dumpregs(u *ureg) {
|
||||||
|
print("ax ", hex(u.ax), "\n")
|
||||||
|
print("bx ", hex(u.bx), "\n")
|
||||||
|
print("cx ", hex(u.cx), "\n")
|
||||||
|
print("dx ", hex(u.dx), "\n")
|
||||||
|
print("di ", hex(u.di), "\n")
|
||||||
|
print("si ", hex(u.si), "\n")
|
||||||
|
print("bp ", hex(u.bp), "\n")
|
||||||
|
print("sp ", hex(u.sp), "\n")
|
||||||
|
print("pc ", hex(u.pc), "\n")
|
||||||
|
print("flags ", hex(u.flags), "\n")
|
||||||
|
print("cs ", hex(u.cs), "\n")
|
||||||
|
print("fs ", hex(u.fs), "\n")
|
||||||
|
print("gs ", hex(u.gs), "\n")
|
||||||
|
}
|
||||||
|
@ -32,3 +32,37 @@ type ureg struct {
|
|||||||
sp uint64 /* sp */
|
sp uint64 /* sp */
|
||||||
ss uint64 /* old stack segment */
|
ss uint64 /* old stack segment */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type sigctxt struct {
|
||||||
|
u *ureg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *sigctxt) pc() uintptr { return uintptr(c.u.ip) }
|
||||||
|
func (c *sigctxt) sp() uintptr { return uintptr(c.u.sp) }
|
||||||
|
|
||||||
|
func (c *sigctxt) setpc(x uintptr) { c.u.ip = uint64(x) }
|
||||||
|
func (c *sigctxt) setsp(x uintptr) { c.u.sp = uint64(x) }
|
||||||
|
|
||||||
|
func dumpregs(u *ureg) {
|
||||||
|
print("ax ", hex(u.ax), "\n")
|
||||||
|
print("bx ", hex(u.bx), "\n")
|
||||||
|
print("cx ", hex(u.cx), "\n")
|
||||||
|
print("dx ", hex(u.dx), "\n")
|
||||||
|
print("di ", hex(u.di), "\n")
|
||||||
|
print("si ", hex(u.si), "\n")
|
||||||
|
print("bp ", hex(u.bp), "\n")
|
||||||
|
print("sp ", hex(u.sp), "\n")
|
||||||
|
print("r8 ", hex(u.r8), "\n")
|
||||||
|
print("r9 ", hex(u.r9), "\n")
|
||||||
|
print("r10 ", hex(u.r10), "\n")
|
||||||
|
print("r11 ", hex(u.r11), "\n")
|
||||||
|
print("r12 ", hex(u.r12), "\n")
|
||||||
|
print("r13 ", hex(u.r13), "\n")
|
||||||
|
print("r14 ", hex(u.r14), "\n")
|
||||||
|
print("r15 ", hex(u.r15), "\n")
|
||||||
|
print("ip ", hex(u.ip), "\n")
|
||||||
|
print("flags ", hex(u.flags), "\n")
|
||||||
|
print("cs ", hex(u.cs), "\n")
|
||||||
|
print("fs ", hex(u.fs), "\n")
|
||||||
|
print("gs ", hex(u.gs), "\n")
|
||||||
|
}
|
||||||
|
@ -6,22 +6,6 @@ package runtime
|
|||||||
|
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
func dumpregs(u *ureg) {
|
|
||||||
print("ax ", hex(u.ax), "\n")
|
|
||||||
print("bx ", hex(u.bx), "\n")
|
|
||||||
print("cx ", hex(u.cx), "\n")
|
|
||||||
print("dx ", hex(u.dx), "\n")
|
|
||||||
print("di ", hex(u.di), "\n")
|
|
||||||
print("si ", hex(u.si), "\n")
|
|
||||||
print("bp ", hex(u.bp), "\n")
|
|
||||||
print("sp ", hex(u.sp), "\n")
|
|
||||||
print("pc ", hex(u.pc), "\n")
|
|
||||||
print("flags ", hex(u.flags), "\n")
|
|
||||||
print("cs ", hex(u.cs), "\n")
|
|
||||||
print("fs ", hex(u.fs), "\n")
|
|
||||||
print("gs ", hex(u.gs), "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func sighandler(_ureg *ureg, note *byte, gp *g) int {
|
func sighandler(_ureg *ureg, note *byte, gp *g) int {
|
||||||
_g_ := getg()
|
_g_ := getg()
|
||||||
var t sigTabT
|
var t sigTabT
|
||||||
@ -30,6 +14,8 @@ func sighandler(_ureg *ureg, note *byte, gp *g) int {
|
|||||||
var sig int
|
var sig int
|
||||||
var flags int
|
var flags int
|
||||||
|
|
||||||
|
c := &sigctxt{_ureg}
|
||||||
|
|
||||||
// The kernel will never pass us a nil note or ureg so we probably
|
// The kernel will never pass us a nil note or ureg so we probably
|
||||||
// made a mistake somewhere in sigtramp.
|
// made a mistake somewhere in sigtramp.
|
||||||
if _ureg == nil || note == nil {
|
if _ureg == nil || note == nil {
|
||||||
@ -65,24 +51,24 @@ func sighandler(_ureg *ureg, note *byte, gp *g) int {
|
|||||||
// we can reliably access it from the panic routines.
|
// we can reliably access it from the panic routines.
|
||||||
memmove(unsafe.Pointer(_g_.m.notesig), unsafe.Pointer(note), uintptr(length+1))
|
memmove(unsafe.Pointer(_g_.m.notesig), unsafe.Pointer(note), uintptr(length+1))
|
||||||
gp.sig = uint32(sig)
|
gp.sig = uint32(sig)
|
||||||
gp.sigpc = uintptr(_ureg.pc)
|
gp.sigpc = c.pc()
|
||||||
// Only push sigpanic if PC != 0.
|
// Only push sigpanic if PC != 0.
|
||||||
//
|
//
|
||||||
// If PC == 0, probably panicked because of a call to a nil func.
|
// If PC == 0, probably panicked because of a call to a nil func.
|
||||||
// Not pushing that onto SP will make the trace look like a call
|
// Not pushing that onto SP will make the trace look like a call
|
||||||
// to sigpanic instead. (Otherwise the trace will end at
|
// to sigpanic instead. (Otherwise the trace will end at
|
||||||
// sigpanic and we won't get to see who faulted).
|
// sigpanic and we won't get to see who faulted).
|
||||||
if _ureg.pc != 0 {
|
if c.pc() != 0 {
|
||||||
sp := _ureg.sp
|
sp := c.sp()
|
||||||
if regSize > ptrSize {
|
if regSize > ptrSize {
|
||||||
sp -= ptrSize
|
sp -= ptrSize
|
||||||
*(*uintptr)(unsafe.Pointer(uintptr(sp))) = 0
|
*(*uintptr)(unsafe.Pointer(sp)) = 0
|
||||||
}
|
}
|
||||||
sp -= ptrSize
|
sp -= ptrSize
|
||||||
*(*uintptr)(unsafe.Pointer(uintptr(sp))) = uintptr(_ureg.pc)
|
*(*uintptr)(unsafe.Pointer(sp)) = c.pc()
|
||||||
_ureg.sp = sp
|
c.setsp(sp)
|
||||||
}
|
}
|
||||||
_ureg.pc = uint32(funcPC(sigpanic))
|
c.setpc(funcPC(sigpanic))
|
||||||
return _NCONT
|
return _NCONT
|
||||||
}
|
}
|
||||||
if flags&_SigNotify != 0 {
|
if flags&_SigNotify != 0 {
|
||||||
@ -101,11 +87,11 @@ Throw:
|
|||||||
_g_.m.caughtsig = gp
|
_g_.m.caughtsig = gp
|
||||||
startpanic()
|
startpanic()
|
||||||
print(gostringnocopy(note), "\n")
|
print(gostringnocopy(note), "\n")
|
||||||
print("PC=", hex(_ureg.pc), "\n")
|
print("PC=", hex(c.pc()), "\n")
|
||||||
print("\n")
|
print("\n")
|
||||||
if gotraceback(&docrash) > 0 {
|
if gotraceback(&docrash) > 0 {
|
||||||
goroutineheader(gp)
|
goroutineheader(gp)
|
||||||
tracebacktrap(uintptr(_ureg.pc), uintptr(_ureg.sp), 0, gp)
|
tracebacktrap(c.pc(), c.sp(), 0, gp)
|
||||||
tracebackothers(gp)
|
tracebackothers(gp)
|
||||||
print("\n")
|
print("\n")
|
||||||
dumpregs(_ureg)
|
dumpregs(_ureg)
|
@ -1,139 +0,0 @@
|
|||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
func dumpregs(u *ureg) {
|
|
||||||
print("ax ", hex(u.ax), "\n")
|
|
||||||
print("bx ", hex(u.bx), "\n")
|
|
||||||
print("cx ", hex(u.cx), "\n")
|
|
||||||
print("dx ", hex(u.dx), "\n")
|
|
||||||
print("di ", hex(u.di), "\n")
|
|
||||||
print("si ", hex(u.si), "\n")
|
|
||||||
print("bp ", hex(u.bp), "\n")
|
|
||||||
print("sp ", hex(u.sp), "\n")
|
|
||||||
print("r8 ", hex(u.r8), "\n")
|
|
||||||
print("r9 ", hex(u.r9), "\n")
|
|
||||||
print("r10 ", hex(u.r10), "\n")
|
|
||||||
print("r11 ", hex(u.r11), "\n")
|
|
||||||
print("r12 ", hex(u.r12), "\n")
|
|
||||||
print("r13 ", hex(u.r13), "\n")
|
|
||||||
print("r14 ", hex(u.r14), "\n")
|
|
||||||
print("r15 ", hex(u.r15), "\n")
|
|
||||||
print("ip ", hex(u.ip), "\n")
|
|
||||||
print("flags ", hex(u.flags), "\n")
|
|
||||||
print("cs ", hex(uint64(u.cs)), "\n")
|
|
||||||
print("fs ", hex(uint64(u.fs)), "\n")
|
|
||||||
print("gs ", hex(uint64(u.gs)), "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func sighandler(_ureg *ureg, note *byte, gp *g) int {
|
|
||||||
_g_ := getg()
|
|
||||||
var t sigTabT
|
|
||||||
var docrash bool
|
|
||||||
var length int
|
|
||||||
var sig int
|
|
||||||
var flags int
|
|
||||||
|
|
||||||
// The kernel will never pass us a nil note or ureg so we probably
|
|
||||||
// made a mistake somewhere in sigtramp.
|
|
||||||
if _ureg == nil || note == nil {
|
|
||||||
print("sighandler: ureg ", _ureg, " note ", note, "\n")
|
|
||||||
goto Throw
|
|
||||||
}
|
|
||||||
// Check that the note is no more than ERRMAX bytes (including
|
|
||||||
// the trailing NUL). We should never receive a longer note.
|
|
||||||
length = findnull(note)
|
|
||||||
if length > _ERRMAX-1 {
|
|
||||||
print("sighandler: note is longer than ERRMAX\n")
|
|
||||||
goto Throw
|
|
||||||
}
|
|
||||||
// See if the note matches one of the patterns in sigtab.
|
|
||||||
// Notes that do not match any pattern can be handled at a higher
|
|
||||||
// level by the program but will otherwise be ignored.
|
|
||||||
flags = _SigNotify
|
|
||||||
for sig, t = range sigtable {
|
|
||||||
n := len(t.name)
|
|
||||||
if length < n {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strncmp(note, &t.name[0], uintptr(n)) == 0 {
|
|
||||||
flags = t.flags
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if flags&_SigGoExit != 0 {
|
|
||||||
exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix.
|
|
||||||
}
|
|
||||||
if flags&_SigPanic != 0 {
|
|
||||||
// Copy the error string from sigtramp's stack into m->notesig so
|
|
||||||
// we can reliably access it from the panic routines.
|
|
||||||
memmove(unsafe.Pointer(_g_.m.notesig), unsafe.Pointer(note), uintptr(length+1))
|
|
||||||
gp.sig = uint32(sig)
|
|
||||||
gp.sigpc = uintptr(_ureg.ip)
|
|
||||||
// Only push sigpanic if PC != 0.
|
|
||||||
//
|
|
||||||
// If PC == 0, probably panicked because of a call to a nil func.
|
|
||||||
// Not pushing that onto SP will make the trace look like a call
|
|
||||||
// to sigpanic instead. (Otherwise the trace will end at
|
|
||||||
// sigpanic and we won't get to see who faulted).
|
|
||||||
if _ureg.ip != 0 {
|
|
||||||
sp := _ureg.sp
|
|
||||||
if regSize > ptrSize {
|
|
||||||
sp -= ptrSize
|
|
||||||
*(*uintptr)(unsafe.Pointer(uintptr(sp))) = 0
|
|
||||||
}
|
|
||||||
sp -= ptrSize
|
|
||||||
*(*uintptr)(unsafe.Pointer(uintptr(sp))) = uintptr(_ureg.ip)
|
|
||||||
_ureg.sp = sp
|
|
||||||
}
|
|
||||||
_ureg.ip = uint64(funcPC(sigpanic))
|
|
||||||
return _NCONT
|
|
||||||
}
|
|
||||||
if flags&_SigNotify != 0 {
|
|
||||||
// TODO(ality): See if os/signal wants it.
|
|
||||||
//if(sigsend(...))
|
|
||||||
// return _NCONT;
|
|
||||||
}
|
|
||||||
if flags&_SigKill != 0 {
|
|
||||||
goto Exit
|
|
||||||
}
|
|
||||||
if flags&_SigThrow == 0 {
|
|
||||||
return _NCONT
|
|
||||||
}
|
|
||||||
Throw:
|
|
||||||
_g_.m.throwing = 1
|
|
||||||
_g_.m.caughtsig = gp
|
|
||||||
startpanic()
|
|
||||||
print(gostringnocopy(note), "\n")
|
|
||||||
print("PC=", hex(_ureg.ip), "\n")
|
|
||||||
print("\n")
|
|
||||||
if gotraceback(&docrash) > 0 {
|
|
||||||
goroutineheader(gp)
|
|
||||||
tracebacktrap(uintptr(_ureg.ip), uintptr(_ureg.sp), 0, gp)
|
|
||||||
tracebackothers(gp)
|
|
||||||
print("\n")
|
|
||||||
dumpregs(_ureg)
|
|
||||||
}
|
|
||||||
if docrash {
|
|
||||||
crash()
|
|
||||||
}
|
|
||||||
Exit:
|
|
||||||
goexitsall(note)
|
|
||||||
exits(note)
|
|
||||||
return _NDFLT // not reached
|
|
||||||
}
|
|
||||||
|
|
||||||
func sigenable(sig uint32) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func sigdisable(sig uint32) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func resetcpuprofiler(hz int32) {
|
|
||||||
// TODO: Enable profiling interrupts.
|
|
||||||
getg().m.profilehz = hz
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user