mirror of
https://github.com/golang/go.git
synced 2025-05-29 11:25:43 +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
|
||||
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 */
|
||||
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"
|
||||
|
||||
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 {
|
||||
_g_ := getg()
|
||||
var t sigTabT
|
||||
@ -30,6 +14,8 @@ func sighandler(_ureg *ureg, note *byte, gp *g) int {
|
||||
var sig int
|
||||
var flags int
|
||||
|
||||
c := &sigctxt{_ureg}
|
||||
|
||||
// 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 {
|
||||
@ -65,24 +51,24 @@ func sighandler(_ureg *ureg, note *byte, gp *g) int {
|
||||
// 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.pc)
|
||||
gp.sigpc = c.pc()
|
||||
// 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.pc != 0 {
|
||||
sp := _ureg.sp
|
||||
if c.pc() != 0 {
|
||||
sp := c.sp()
|
||||
if regSize > ptrSize {
|
||||
sp -= ptrSize
|
||||
*(*uintptr)(unsafe.Pointer(uintptr(sp))) = 0
|
||||
*(*uintptr)(unsafe.Pointer(sp)) = 0
|
||||
}
|
||||
sp -= ptrSize
|
||||
*(*uintptr)(unsafe.Pointer(uintptr(sp))) = uintptr(_ureg.pc)
|
||||
_ureg.sp = sp
|
||||
*(*uintptr)(unsafe.Pointer(sp)) = c.pc()
|
||||
c.setsp(sp)
|
||||
}
|
||||
_ureg.pc = uint32(funcPC(sigpanic))
|
||||
c.setpc(funcPC(sigpanic))
|
||||
return _NCONT
|
||||
}
|
||||
if flags&_SigNotify != 0 {
|
||||
@ -101,11 +87,11 @@ Throw:
|
||||
_g_.m.caughtsig = gp
|
||||
startpanic()
|
||||
print(gostringnocopy(note), "\n")
|
||||
print("PC=", hex(_ureg.pc), "\n")
|
||||
print("PC=", hex(c.pc()), "\n")
|
||||
print("\n")
|
||||
if gotraceback(&docrash) > 0 {
|
||||
goroutineheader(gp)
|
||||
tracebacktrap(uintptr(_ureg.pc), uintptr(_ureg.sp), 0, gp)
|
||||
tracebacktrap(c.pc(), c.sp(), 0, gp)
|
||||
tracebackothers(gp)
|
||||
print("\n")
|
||||
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