mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.cc] runtime: convert signal handlers from C to Go
This code overused macros and could not be converted automatically. Instead a new sigctxt type had to be defined for each os/arch combination, with a common (implicit) interface used by the arch-specific signal handler code. [This CL is part of the removal of C code from package runtime. See golang.org/s/dev.cc for an overview.] LGTM=r R=r CC=austin, dvyukov, golang-codereviews, iant, khr https://golang.org/cl/168500044
This commit is contained in:
parent
9f99d531a0
commit
2d917c0c26
27 changed files with 882 additions and 829 deletions
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
#include "runtime.h"
|
||||
|
||||
void
|
||||
runtime·sigenable_m(void)
|
||||
{
|
||||
uint32 s;
|
||||
|
||||
s = g->m->scalararg[0];
|
||||
g->m->scalararg[0] = 0;
|
||||
runtime·sigenable(s);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·sigdisable_m(void)
|
||||
{
|
||||
uint32 s;
|
||||
|
||||
s = g->m->scalararg[0];
|
||||
g->m->scalararg[0] = 0;
|
||||
runtime·sigdisable(s);
|
||||
}
|
||||
15
src/runtime/signal.go
Normal file
15
src/runtime/signal.go
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2014 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
|
||||
|
||||
func sigenable_m() {
|
||||
_g_ := getg()
|
||||
sigenable(uint32(_g_.m.scalararg[0]))
|
||||
}
|
||||
|
||||
func sigdisable_m() {
|
||||
_g_ := getg()
|
||||
sigdisable(uint32(_g_.m.scalararg[0]))
|
||||
}
|
||||
111
src/runtime/signal1_unix.go
Normal file
111
src/runtime/signal1_unix.go
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package runtime
|
||||
|
||||
const (
|
||||
_SIG_DFL uintptr = 0
|
||||
_SIG_IGN uintptr = 1
|
||||
)
|
||||
|
||||
func initsig() {
|
||||
// _NSIG is the number of signals on this operating system.
|
||||
// sigtable should describe what to do for all the possible signals.
|
||||
if len(sigtable) != _NSIG {
|
||||
print("runtime: len(sigtable)=", len(sigtable), " _NSIG=", _NSIG, "\n")
|
||||
gothrow("initsig")
|
||||
}
|
||||
|
||||
// First call: basic setup.
|
||||
for i := int32(0); i < _NSIG; i++ {
|
||||
t := &sigtable[i]
|
||||
if t.flags == 0 || t.flags&_SigDefault != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// For some signals, we respect an inherited SIG_IGN handler
|
||||
// rather than insist on installing our own default handler.
|
||||
// Even these signals can be fetched using the os/signal package.
|
||||
switch i {
|
||||
case _SIGHUP, _SIGINT:
|
||||
if getsig(i) == _SIG_IGN {
|
||||
t.flags = _SigNotify | _SigIgnored
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
t.flags |= _SigHandling
|
||||
setsig(i, funcPC(sighandler), true)
|
||||
}
|
||||
}
|
||||
|
||||
func sigenable(sig uint32) {
|
||||
if sig >= uint32(len(sigtable)) {
|
||||
return
|
||||
}
|
||||
|
||||
t := &sigtable[sig]
|
||||
if t.flags&_SigNotify != 0 && t.flags&_SigHandling == 0 {
|
||||
t.flags |= _SigHandling
|
||||
if getsig(int32(sig)) == _SIG_IGN {
|
||||
t.flags |= _SigIgnored
|
||||
}
|
||||
setsig(int32(sig), funcPC(sighandler), true)
|
||||
}
|
||||
}
|
||||
|
||||
func sigdisable(sig uint32) {
|
||||
if sig >= uint32(len(sigtable)) {
|
||||
return
|
||||
}
|
||||
|
||||
t := &sigtable[sig]
|
||||
if t.flags&_SigNotify != 0 && t.flags&_SigHandling != 0 {
|
||||
t.flags &^= _SigHandling
|
||||
if t.flags&_SigIgnored != 0 {
|
||||
setsig(int32(sig), _SIG_IGN, true)
|
||||
} else {
|
||||
setsig(int32(sig), _SIG_DFL, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func resetcpuprofiler(hz int32) {
|
||||
var it itimerval
|
||||
if hz == 0 {
|
||||
setitimer(_ITIMER_PROF, &it, nil)
|
||||
} else {
|
||||
it.it_interval.tv_sec = 0
|
||||
it.it_interval.set_usec(1000000 / hz)
|
||||
it.it_value = it.it_interval
|
||||
setitimer(_ITIMER_PROF, &it, nil)
|
||||
}
|
||||
_g_ := getg()
|
||||
_g_.m.profilehz = hz
|
||||
}
|
||||
|
||||
func sigpipe() {
|
||||
setsig(_SIGPIPE, _SIG_DFL, false)
|
||||
raise(_SIGPIPE)
|
||||
}
|
||||
|
||||
func crash() {
|
||||
if GOOS == "darwin" {
|
||||
// OS X core dumps are linear dumps of the mapped memory,
|
||||
// from the first virtual byte to the last, with zeros in the gaps.
|
||||
// Because of the way we arrange the address space on 64-bit systems,
|
||||
// this means the OS X core file will be >128 GB and even on a zippy
|
||||
// workstation can take OS X well over an hour to write (uninterruptible).
|
||||
// Save users from making that mistake.
|
||||
if ptrSize == 8 {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
unblocksignals()
|
||||
setsig(_SIGABRT, _SIG_DFL, false)
|
||||
raise(_SIGABRT)
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
// +build darwin dragonfly freebsd linux nacl netbsd openbsd
|
||||
|
||||
#include "runtime.h"
|
||||
#include "defs_GOOS_GOARCH.h"
|
||||
#include "os_GOOS.h"
|
||||
#include "signal_GOOS_GOARCH.h"
|
||||
#include "signals_GOOS.h"
|
||||
|
||||
void
|
||||
runtime·dumpregs(Siginfo *info, void *ctxt)
|
||||
{
|
||||
USED(info);
|
||||
USED(ctxt);
|
||||
|
||||
runtime·printf("eax %x\n", SIG_EAX(info, ctxt));
|
||||
runtime·printf("ebx %x\n", SIG_EBX(info, ctxt));
|
||||
runtime·printf("ecx %x\n", SIG_ECX(info, ctxt));
|
||||
runtime·printf("edx %x\n", SIG_EDX(info, ctxt));
|
||||
runtime·printf("edi %x\n", SIG_EDI(info, ctxt));
|
||||
runtime·printf("esi %x\n", SIG_ESI(info, ctxt));
|
||||
runtime·printf("ebp %x\n", SIG_EBP(info, ctxt));
|
||||
runtime·printf("esp %x\n", SIG_ESP(info, ctxt));
|
||||
runtime·printf("eip %x\n", SIG_EIP(info, ctxt));
|
||||
runtime·printf("eflags %x\n", SIG_EFLAGS(info, ctxt));
|
||||
runtime·printf("cs %x\n", SIG_CS(info, ctxt));
|
||||
runtime·printf("fs %x\n", SIG_FS(info, ctxt));
|
||||
runtime·printf("gs %x\n", SIG_GS(info, ctxt));
|
||||
}
|
||||
|
||||
void
|
||||
runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
||||
{
|
||||
uintptr *sp;
|
||||
SigTab *t;
|
||||
bool crash;
|
||||
|
||||
if(sig == SIGPROF) {
|
||||
runtime·sigprof((byte*)SIG_EIP(info, ctxt), (byte*)SIG_ESP(info, ctxt), nil, gp, g->m);
|
||||
return;
|
||||
}
|
||||
|
||||
t = &runtime·sigtab[sig];
|
||||
if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
|
||||
// Make it look like a call to the signal func.
|
||||
// Have to pass arguments out of band since
|
||||
// augmenting the stack frame would break
|
||||
// the unwinding code.
|
||||
gp->sig = sig;
|
||||
gp->sigcode0 = SIG_CODE0(info, ctxt);
|
||||
gp->sigcode1 = SIG_CODE1(info, ctxt);
|
||||
gp->sigpc = SIG_EIP(info, ctxt);
|
||||
|
||||
#ifdef GOOS_darwin
|
||||
// Work around Leopard bug that doesn't set FPE_INTDIV.
|
||||
// Look at instruction to see if it is a divide.
|
||||
// Not necessary in Snow Leopard (si_code will be != 0).
|
||||
if(sig == SIGFPE && gp->sigcode0 == 0) {
|
||||
byte *pc;
|
||||
pc = (byte*)gp->sigpc;
|
||||
if(pc[0] == 0x66) // 16-bit instruction prefix
|
||||
pc++;
|
||||
if(pc[0] == 0xF6 || pc[0] == 0xF7)
|
||||
gp->sigcode0 = FPE_INTDIV;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Only push runtime·sigpanic if eip != 0.
|
||||
// If eip == 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 runtime·sigpanic instead.
|
||||
// (Otherwise the trace will end at runtime·sigpanic and we
|
||||
// won't get to see who faulted.)
|
||||
if(SIG_EIP(info, ctxt) != 0) {
|
||||
sp = (uintptr*)SIG_ESP(info, ctxt);
|
||||
*--sp = SIG_EIP(info, ctxt);
|
||||
SIG_ESP(info, ctxt) = (uintptr)sp;
|
||||
}
|
||||
SIG_EIP(info, ctxt) = (uintptr)runtime·sigpanic;
|
||||
return;
|
||||
}
|
||||
|
||||
if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
|
||||
if(runtime·sigsend(sig))
|
||||
return;
|
||||
if(t->flags & SigKill)
|
||||
runtime·exit(2);
|
||||
if(!(t->flags & SigThrow))
|
||||
return;
|
||||
|
||||
g->m->throwing = 1;
|
||||
g->m->caughtsig = gp;
|
||||
runtime·startpanic();
|
||||
|
||||
if(sig < 0 || sig >= NSIG)
|
||||
runtime·printf("Signal %d\n", sig);
|
||||
else
|
||||
runtime·printf("%s\n", runtime·sigtab[sig].name);
|
||||
|
||||
runtime·printf("PC=%x\n", SIG_EIP(info, ctxt));
|
||||
if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
|
||||
runtime·printf("signal arrived during cgo execution\n");
|
||||
gp = g->m->lockedg;
|
||||
}
|
||||
runtime·printf("\n");
|
||||
|
||||
if(runtime·gotraceback(&crash)){
|
||||
runtime·goroutineheader(gp);
|
||||
runtime·tracebacktrap(SIG_EIP(info, ctxt), SIG_ESP(info, ctxt), 0, gp);
|
||||
runtime·tracebackothers(gp);
|
||||
runtime·printf("\n");
|
||||
runtime·dumpregs(info, ctxt);
|
||||
}
|
||||
|
||||
if(crash)
|
||||
runtime·crash();
|
||||
|
||||
runtime·exit(2);
|
||||
}
|
||||
131
src/runtime/signal_386.go
Normal file
131
src/runtime/signal_386.go
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
// +build darwin dragonfly freebsd linux nacl netbsd openbsd
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func dumpregs(c *sigctxt) {
|
||||
print("eax ", hex(c.eax()), "\n")
|
||||
print("ebx ", hex(c.ebx()), "\n")
|
||||
print("ecx ", hex(c.ecx()), "\n")
|
||||
print("edx ", hex(c.edx()), "\n")
|
||||
print("edi ", hex(c.edi()), "\n")
|
||||
print("esi ", hex(c.esi()), "\n")
|
||||
print("ebp ", hex(c.ebp()), "\n")
|
||||
print("esp ", hex(c.esp()), "\n")
|
||||
print("eip ", hex(c.eip()), "\n")
|
||||
print("eflags ", hex(c.eflags()), "\n")
|
||||
print("cs ", hex(c.cs()), "\n")
|
||||
print("fs ", hex(c.fs()), "\n")
|
||||
print("gs ", hex(c.gs()), "\n")
|
||||
}
|
||||
|
||||
func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
|
||||
_g_ := getg()
|
||||
c := &sigctxt{info, ctxt}
|
||||
|
||||
if sig == _SIGPROF {
|
||||
sigprof((*byte)(unsafe.Pointer(uintptr(c.eip()))), (*byte)(unsafe.Pointer(uintptr(c.esp()))), nil, gp, _g_.m)
|
||||
return
|
||||
}
|
||||
|
||||
flags := int32(_SigThrow)
|
||||
if sig < uint32(len(sigtable)) {
|
||||
flags = sigtable[sig].flags
|
||||
}
|
||||
if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
|
||||
// Make it look like a call to the signal func.
|
||||
// Have to pass arguments out of band since
|
||||
// augmenting the stack frame would break
|
||||
// the unwinding code.
|
||||
gp.sig = sig
|
||||
gp.sigcode0 = uintptr(c.sigcode())
|
||||
gp.sigcode1 = uintptr(c.sigaddr())
|
||||
gp.sigpc = uintptr(c.eip())
|
||||
|
||||
if GOOS == "darwin" {
|
||||
// Work around Leopard bug that doesn't set FPE_INTDIV.
|
||||
// Look at instruction to see if it is a divide.
|
||||
// Not necessary in Snow Leopard (si_code will be != 0).
|
||||
if sig == _SIGFPE && gp.sigcode0 == 0 {
|
||||
pc := (*[4]byte)(unsafe.Pointer(gp.sigpc))
|
||||
i := 0
|
||||
if pc[i] == 0x66 { // 16-bit instruction prefix
|
||||
i++
|
||||
}
|
||||
if pc[i] == 0xF6 || pc[i] == 0xF7 {
|
||||
gp.sigcode0 = _FPE_INTDIV
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only push runtime.sigpanic if rip != 0.
|
||||
// If rip == 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 runtime.sigpanic instead.
|
||||
// (Otherwise the trace will end at runtime.sigpanic and we
|
||||
// won't get to see who faulted.)
|
||||
if c.eip() != 0 {
|
||||
sp := c.esp()
|
||||
if regSize > ptrSize {
|
||||
sp -= ptrSize
|
||||
*(*uintptr)(unsafe.Pointer(uintptr(sp))) = 0
|
||||
}
|
||||
sp -= ptrSize
|
||||
*(*uintptr)(unsafe.Pointer(uintptr(sp))) = uintptr(c.eip())
|
||||
c.set_esp(sp)
|
||||
}
|
||||
c.set_eip(uint32(funcPC(sigpanic)))
|
||||
return
|
||||
}
|
||||
|
||||
if c.sigcode() == _SI_USER || flags&_SigNotify != 0 {
|
||||
if sigsend(sig) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if flags&_SigKill != 0 {
|
||||
exit(2)
|
||||
}
|
||||
|
||||
if flags&_SigThrow == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
_g_.m.throwing = 1
|
||||
_g_.m.caughtsig = gp
|
||||
startpanic()
|
||||
|
||||
if sig < uint32(len(sigtable)) {
|
||||
print(sigtable[sig].name, "\n")
|
||||
} else {
|
||||
print("Signal ", sig, "\n")
|
||||
}
|
||||
|
||||
print("PC=", hex(c.eip()), "\n")
|
||||
if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
|
||||
print("signal arrived during cgo execution\n")
|
||||
gp = _g_.m.lockedg
|
||||
}
|
||||
print("\n")
|
||||
|
||||
var docrash bool
|
||||
if gotraceback(&docrash) > 0 {
|
||||
goroutineheader(gp)
|
||||
tracebacktrap(uintptr(c.eip()), uintptr(c.esp()), 0, gp)
|
||||
tracebackothers(gp)
|
||||
print("\n")
|
||||
dumpregs(c)
|
||||
}
|
||||
|
||||
if docrash {
|
||||
crash()
|
||||
}
|
||||
|
||||
exit(2)
|
||||
}
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
// +build amd64 amd64p32
|
||||
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
|
||||
|
||||
#include "runtime.h"
|
||||
#include "defs_GOOS_GOARCH.h"
|
||||
#include "os_GOOS.h"
|
||||
#include "signal_GOOS_GOARCH.h"
|
||||
#include "signals_GOOS.h"
|
||||
|
||||
void
|
||||
runtime·dumpregs(Siginfo *info, void *ctxt)
|
||||
{
|
||||
USED(info);
|
||||
USED(ctxt);
|
||||
|
||||
runtime·printf("rax %X\n", SIG_RAX(info, ctxt));
|
||||
runtime·printf("rbx %X\n", SIG_RBX(info, ctxt));
|
||||
runtime·printf("rcx %X\n", SIG_RCX(info, ctxt));
|
||||
runtime·printf("rdx %X\n", SIG_RDX(info, ctxt));
|
||||
runtime·printf("rdi %X\n", SIG_RDI(info, ctxt));
|
||||
runtime·printf("rsi %X\n", SIG_RSI(info, ctxt));
|
||||
runtime·printf("rbp %X\n", SIG_RBP(info, ctxt));
|
||||
runtime·printf("rsp %X\n", SIG_RSP(info, ctxt));
|
||||
runtime·printf("r8 %X\n", SIG_R8(info, ctxt) );
|
||||
runtime·printf("r9 %X\n", SIG_R9(info, ctxt) );
|
||||
runtime·printf("r10 %X\n", SIG_R10(info, ctxt));
|
||||
runtime·printf("r11 %X\n", SIG_R11(info, ctxt));
|
||||
runtime·printf("r12 %X\n", SIG_R12(info, ctxt));
|
||||
runtime·printf("r13 %X\n", SIG_R13(info, ctxt));
|
||||
runtime·printf("r14 %X\n", SIG_R14(info, ctxt));
|
||||
runtime·printf("r15 %X\n", SIG_R15(info, ctxt));
|
||||
runtime·printf("rip %X\n", SIG_RIP(info, ctxt));
|
||||
runtime·printf("rflags %X\n", SIG_RFLAGS(info, ctxt));
|
||||
runtime·printf("cs %X\n", SIG_CS(info, ctxt));
|
||||
runtime·printf("fs %X\n", SIG_FS(info, ctxt));
|
||||
runtime·printf("gs %X\n", SIG_GS(info, ctxt));
|
||||
}
|
||||
|
||||
void
|
||||
runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
||||
{
|
||||
uintptr *sp;
|
||||
SigTab *t;
|
||||
bool crash;
|
||||
|
||||
if(sig == SIGPROF) {
|
||||
runtime·sigprof((byte*)SIG_RIP(info, ctxt), (byte*)SIG_RSP(info, ctxt), nil, gp, g->m);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef GOOS_darwin
|
||||
// x86-64 has 48-bit virtual addresses. The top 16 bits must echo bit 47.
|
||||
// The hardware delivers a different kind of fault for a malformed address
|
||||
// than it does for an attempt to access a valid but unmapped address.
|
||||
// OS X 10.9.2 mishandles the malformed address case, making it look like
|
||||
// a user-generated signal (like someone ran kill -SEGV ourpid).
|
||||
// We pass user-generated signals to os/signal, or else ignore them.
|
||||
// Doing that here - and returning to the faulting code - results in an
|
||||
// infinite loop. It appears the best we can do is rewrite what the kernel
|
||||
// delivers into something more like the truth. The address used below
|
||||
// has very little chance of being the one that caused the fault, but it is
|
||||
// malformed, it is clearly not a real pointer, and if it does get printed
|
||||
// in real life, people will probably search for it and find this code.
|
||||
// There are no Google hits for b01dfacedebac1e or 0xb01dfacedebac1e
|
||||
// as I type this comment.
|
||||
if(sig == SIGSEGV && SIG_CODE0(info, ctxt) == SI_USER) {
|
||||
SIG_CODE0(info, ctxt) = SI_USER+1;
|
||||
info->si_addr = (void*)(uintptr)0xb01dfacedebac1eULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
t = &runtime·sigtab[sig];
|
||||
if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
|
||||
// Make it look like a call to the signal func.
|
||||
// Have to pass arguments out of band since
|
||||
// augmenting the stack frame would break
|
||||
// the unwinding code.
|
||||
gp->sig = sig;
|
||||
gp->sigcode0 = SIG_CODE0(info, ctxt);
|
||||
gp->sigcode1 = SIG_CODE1(info, ctxt);
|
||||
gp->sigpc = SIG_RIP(info, ctxt);
|
||||
|
||||
#ifdef GOOS_darwin
|
||||
// Work around Leopard bug that doesn't set FPE_INTDIV.
|
||||
// Look at instruction to see if it is a divide.
|
||||
// Not necessary in Snow Leopard (si_code will be != 0).
|
||||
if(sig == SIGFPE && gp->sigcode0 == 0) {
|
||||
byte *pc;
|
||||
pc = (byte*)gp->sigpc;
|
||||
if((pc[0]&0xF0) == 0x40) // 64-bit REX prefix
|
||||
pc++;
|
||||
else if(pc[0] == 0x66) // 16-bit instruction prefix
|
||||
pc++;
|
||||
if(pc[0] == 0xF6 || pc[0] == 0xF7)
|
||||
gp->sigcode0 = FPE_INTDIV;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Only push runtime·sigpanic if rip != 0.
|
||||
// If rip == 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 runtime·sigpanic instead.
|
||||
// (Otherwise the trace will end at runtime·sigpanic and we
|
||||
// won't get to see who faulted.)
|
||||
if(SIG_RIP(info, ctxt) != 0) {
|
||||
sp = (uintptr*)SIG_RSP(info, ctxt);
|
||||
if(sizeof(uintreg) > sizeof(uintptr))
|
||||
*--sp = 0;
|
||||
*--sp = SIG_RIP(info, ctxt);
|
||||
SIG_RSP(info, ctxt) = (uintptr)sp;
|
||||
}
|
||||
SIG_RIP(info, ctxt) = (uintptr)runtime·sigpanic;
|
||||
return;
|
||||
}
|
||||
|
||||
if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
|
||||
if(runtime·sigsend(sig))
|
||||
return;
|
||||
if(t->flags & SigKill)
|
||||
runtime·exit(2);
|
||||
if(!(t->flags & SigThrow))
|
||||
return;
|
||||
|
||||
g->m->throwing = 1;
|
||||
g->m->caughtsig = gp;
|
||||
runtime·startpanic();
|
||||
|
||||
if(sig < 0 || sig >= NSIG)
|
||||
runtime·printf("Signal %d\n", sig);
|
||||
else
|
||||
runtime·printf("%s\n", runtime·sigtab[sig].name);
|
||||
|
||||
runtime·printf("PC=%X\n", SIG_RIP(info, ctxt));
|
||||
if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
|
||||
runtime·printf("signal arrived during cgo execution\n");
|
||||
gp = g->m->lockedg;
|
||||
}
|
||||
runtime·printf("\n");
|
||||
|
||||
if(runtime·gotraceback(&crash)){
|
||||
runtime·goroutineheader(gp);
|
||||
runtime·tracebacktrap(SIG_RIP(info, ctxt), SIG_RSP(info, ctxt), 0, gp);
|
||||
runtime·tracebackothers(gp);
|
||||
runtime·printf("\n");
|
||||
runtime·dumpregs(info, ctxt);
|
||||
}
|
||||
|
||||
if(crash)
|
||||
runtime·crash();
|
||||
|
||||
runtime·exit(2);
|
||||
}
|
||||
163
src/runtime/signal_amd64x.go
Normal file
163
src/runtime/signal_amd64x.go
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
// +build amd64 amd64p32
|
||||
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func dumpregs(c *sigctxt) {
|
||||
print("rax ", hex(c.rax()), "\n")
|
||||
print("rbx ", hex(c.rbx()), "\n")
|
||||
print("rcx ", hex(c.rcx()), "\n")
|
||||
print("rdx ", hex(c.rdx()), "\n")
|
||||
print("rdi ", hex(c.rdi()), "\n")
|
||||
print("rsi ", hex(c.rsi()), "\n")
|
||||
print("rbp ", hex(c.rbp()), "\n")
|
||||
print("rsp ", hex(c.rsp()), "\n")
|
||||
print("r8 ", hex(c.r8()), "\n")
|
||||
print("r9 ", hex(c.r9()), "\n")
|
||||
print("r10 ", hex(c.r10()), "\n")
|
||||
print("r11 ", hex(c.r11()), "\n")
|
||||
print("r12 ", hex(c.r12()), "\n")
|
||||
print("r13 ", hex(c.r13()), "\n")
|
||||
print("r14 ", hex(c.r14()), "\n")
|
||||
print("r15 ", hex(c.r15()), "\n")
|
||||
print("rip ", hex(c.rip()), "\n")
|
||||
print("rflags ", hex(c.rflags()), "\n")
|
||||
print("cs ", hex(c.cs()), "\n")
|
||||
print("fs ", hex(c.fs()), "\n")
|
||||
print("gs ", hex(c.gs()), "\n")
|
||||
}
|
||||
|
||||
func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
|
||||
_g_ := getg()
|
||||
c := &sigctxt{info, ctxt}
|
||||
|
||||
if sig == _SIGPROF {
|
||||
sigprof((*byte)(unsafe.Pointer(uintptr(c.rip()))), (*byte)(unsafe.Pointer(uintptr(c.rsp()))), nil, gp, _g_.m)
|
||||
return
|
||||
}
|
||||
|
||||
if GOOS == "darwin" {
|
||||
// x86-64 has 48-bit virtual addresses. The top 16 bits must echo bit 47.
|
||||
// The hardware delivers a different kind of fault for a malformed address
|
||||
// than it does for an attempt to access a valid but unmapped address.
|
||||
// OS X 10.9.2 mishandles the malformed address case, making it look like
|
||||
// a user-generated signal (like someone ran kill -SEGV ourpid).
|
||||
// We pass user-generated signals to os/signal, or else ignore them.
|
||||
// Doing that here - and returning to the faulting code - results in an
|
||||
// infinite loop. It appears the best we can do is rewrite what the kernel
|
||||
// delivers into something more like the truth. The address used below
|
||||
// has very little chance of being the one that caused the fault, but it is
|
||||
// malformed, it is clearly not a real pointer, and if it does get printed
|
||||
// in real life, people will probably search for it and find this code.
|
||||
// There are no Google hits for b01dfacedebac1e or 0xb01dfacedebac1e
|
||||
// as I type this comment.
|
||||
if sig == _SIGSEGV && c.sigcode() == _SI_USER {
|
||||
c.set_sigcode(_SI_USER + 1)
|
||||
c.set_sigaddr(0xb01dfacedebac1e)
|
||||
}
|
||||
}
|
||||
|
||||
flags := int32(_SigThrow)
|
||||
if sig < uint32(len(sigtable)) {
|
||||
flags = sigtable[sig].flags
|
||||
}
|
||||
if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
|
||||
// Make it look like a call to the signal func.
|
||||
// Have to pass arguments out of band since
|
||||
// augmenting the stack frame would break
|
||||
// the unwinding code.
|
||||
gp.sig = sig
|
||||
gp.sigcode0 = uintptr(c.sigcode())
|
||||
gp.sigcode1 = uintptr(c.sigaddr())
|
||||
gp.sigpc = uintptr(c.rip())
|
||||
|
||||
if GOOS == "darwin" {
|
||||
// Work around Leopard bug that doesn't set FPE_INTDIV.
|
||||
// Look at instruction to see if it is a divide.
|
||||
// Not necessary in Snow Leopard (si_code will be != 0).
|
||||
if sig == _SIGFPE && gp.sigcode0 == 0 {
|
||||
pc := (*[4]byte)(unsafe.Pointer(gp.sigpc))
|
||||
i := 0
|
||||
if pc[i]&0xF0 == 0x40 { // 64-bit REX prefix
|
||||
i++
|
||||
} else if pc[i] == 0x66 { // 16-bit instruction prefix
|
||||
i++
|
||||
}
|
||||
if pc[i] == 0xF6 || pc[i] == 0xF7 {
|
||||
gp.sigcode0 = _FPE_INTDIV
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only push runtime.sigpanic if rip != 0.
|
||||
// If rip == 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 runtime.sigpanic instead.
|
||||
// (Otherwise the trace will end at runtime.sigpanic and we
|
||||
// won't get to see who faulted.)
|
||||
if c.rip() != 0 {
|
||||
sp := c.rsp()
|
||||
if regSize > ptrSize {
|
||||
sp -= ptrSize
|
||||
*(*uintptr)(unsafe.Pointer(uintptr(sp))) = 0
|
||||
}
|
||||
sp -= ptrSize
|
||||
*(*uintptr)(unsafe.Pointer(uintptr(sp))) = uintptr(c.rip())
|
||||
c.set_rsp(sp)
|
||||
}
|
||||
c.set_rip(uint64(funcPC(sigpanic)))
|
||||
return
|
||||
}
|
||||
|
||||
if c.sigcode() == _SI_USER || flags&_SigNotify != 0 {
|
||||
if sigsend(sig) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if flags&_SigKill != 0 {
|
||||
exit(2)
|
||||
}
|
||||
|
||||
if flags&_SigThrow == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
_g_.m.throwing = 1
|
||||
_g_.m.caughtsig = gp
|
||||
startpanic()
|
||||
|
||||
if sig < uint32(len(sigtable)) {
|
||||
print(sigtable[sig].name, "\n")
|
||||
} else {
|
||||
print("Signal ", sig, "\n")
|
||||
}
|
||||
|
||||
print("PC=", hex(c.rip()), "\n")
|
||||
if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
|
||||
print("signal arrived during cgo execution\n")
|
||||
gp = _g_.m.lockedg
|
||||
}
|
||||
print("\n")
|
||||
|
||||
var docrash bool
|
||||
if gotraceback(&docrash) > 0 {
|
||||
goroutineheader(gp)
|
||||
tracebacktrap(uintptr(c.rip()), uintptr(c.rsp()), 0, gp)
|
||||
tracebackothers(gp)
|
||||
print("\n")
|
||||
dumpregs(c)
|
||||
}
|
||||
|
||||
if docrash {
|
||||
crash()
|
||||
}
|
||||
|
||||
exit(2)
|
||||
}
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
// Copyright 2009 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.
|
||||
|
||||
// +build darwin dragonfly freebsd linux nacl netbsd openbsd
|
||||
|
||||
#include "runtime.h"
|
||||
#include "defs_GOOS_GOARCH.h"
|
||||
#include "os_GOOS.h"
|
||||
#include "signal_GOOS_GOARCH.h"
|
||||
#include "signals_GOOS.h"
|
||||
|
||||
void
|
||||
runtime·dumpregs(Siginfo *info, void *ctxt)
|
||||
{
|
||||
USED(info);
|
||||
USED(ctxt);
|
||||
|
||||
runtime·printf("trap %x\n", SIG_TRAP(info, ctxt));
|
||||
runtime·printf("error %x\n", SIG_ERROR(info, ctxt));
|
||||
runtime·printf("oldmask %x\n", SIG_OLDMASK(info, ctxt));
|
||||
runtime·printf("r0 %x\n", SIG_R0(info, ctxt));
|
||||
runtime·printf("r1 %x\n", SIG_R1(info, ctxt));
|
||||
runtime·printf("r2 %x\n", SIG_R2(info, ctxt));
|
||||
runtime·printf("r3 %x\n", SIG_R3(info, ctxt));
|
||||
runtime·printf("r4 %x\n", SIG_R4(info, ctxt));
|
||||
runtime·printf("r5 %x\n", SIG_R5(info, ctxt));
|
||||
runtime·printf("r6 %x\n", SIG_R6(info, ctxt));
|
||||
runtime·printf("r7 %x\n", SIG_R7(info, ctxt));
|
||||
runtime·printf("r8 %x\n", SIG_R8(info, ctxt));
|
||||
runtime·printf("r9 %x\n", SIG_R9(info, ctxt));
|
||||
runtime·printf("r10 %x\n", SIG_R10(info, ctxt));
|
||||
runtime·printf("fp %x\n", SIG_FP(info, ctxt));
|
||||
runtime·printf("ip %x\n", SIG_IP(info, ctxt));
|
||||
runtime·printf("sp %x\n", SIG_SP(info, ctxt));
|
||||
runtime·printf("lr %x\n", SIG_LR(info, ctxt));
|
||||
runtime·printf("pc %x\n", SIG_PC(info, ctxt));
|
||||
runtime·printf("cpsr %x\n", SIG_CPSR(info, ctxt));
|
||||
runtime·printf("fault %x\n", SIG_FAULT(info, ctxt));
|
||||
}
|
||||
|
||||
void
|
||||
runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
||||
{
|
||||
SigTab *t;
|
||||
bool crash;
|
||||
|
||||
if(sig == SIGPROF) {
|
||||
runtime·sigprof((uint8*)SIG_PC(info, ctxt), (uint8*)SIG_SP(info, ctxt), (uint8*)SIG_LR(info, ctxt), gp, g->m);
|
||||
return;
|
||||
}
|
||||
|
||||
t = &runtime·sigtab[sig];
|
||||
if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
|
||||
// Make it look like a call to the signal func.
|
||||
// Have to pass arguments out of band since
|
||||
// augmenting the stack frame would break
|
||||
// the unwinding code.
|
||||
gp->sig = sig;
|
||||
gp->sigcode0 = SIG_CODE0(info, ctxt);
|
||||
gp->sigcode1 = SIG_FAULT(info, ctxt);
|
||||
gp->sigpc = SIG_PC(info, ctxt);
|
||||
|
||||
// We arrange lr, and pc to pretend the panicking
|
||||
// function calls sigpanic directly.
|
||||
// Always save LR to stack so that panics in leaf
|
||||
// functions are correctly handled. This smashes
|
||||
// the stack frame but we're not going back there
|
||||
// anyway.
|
||||
SIG_SP(info, ctxt) -= 4;
|
||||
*(uint32*)SIG_SP(info, ctxt) = SIG_LR(info, ctxt);
|
||||
// Don't bother saving PC if it's zero, which is
|
||||
// probably a call to a nil func: the old link register
|
||||
// is more useful in the stack trace.
|
||||
if(gp->sigpc != 0)
|
||||
SIG_LR(info, ctxt) = gp->sigpc;
|
||||
// In case we are panicking from external C code
|
||||
SIG_R10(info, ctxt) = (uintptr)gp;
|
||||
SIG_PC(info, ctxt) = (uintptr)runtime·sigpanic;
|
||||
return;
|
||||
}
|
||||
|
||||
if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
|
||||
if(runtime·sigsend(sig))
|
||||
return;
|
||||
if(t->flags & SigKill)
|
||||
runtime·exit(2);
|
||||
if(!(t->flags & SigThrow))
|
||||
return;
|
||||
|
||||
g->m->throwing = 1;
|
||||
g->m->caughtsig = gp;
|
||||
if(runtime·panicking) // traceback already printed
|
||||
runtime·exit(2);
|
||||
runtime·panicking = 1;
|
||||
|
||||
if(sig < 0 || sig >= NSIG)
|
||||
runtime·printf("Signal %d\n", sig);
|
||||
else
|
||||
runtime·printf("%s\n", runtime·sigtab[sig].name);
|
||||
|
||||
runtime·printf("PC=%x\n", SIG_PC(info, ctxt));
|
||||
if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
|
||||
runtime·printf("signal arrived during cgo execution\n");
|
||||
gp = g->m->lockedg;
|
||||
}
|
||||
runtime·printf("\n");
|
||||
|
||||
if(runtime·gotraceback(&crash)){
|
||||
runtime·goroutineheader(gp);
|
||||
runtime·tracebacktrap(SIG_PC(info, ctxt), SIG_SP(info, ctxt), SIG_LR(info, ctxt), gp);
|
||||
runtime·tracebackothers(gp);
|
||||
runtime·printf("\n");
|
||||
runtime·dumpregs(info, ctxt);
|
||||
}
|
||||
|
||||
if(crash)
|
||||
runtime·crash();
|
||||
|
||||
runtime·exit(2);
|
||||
}
|
||||
126
src/runtime/signal_arm.go
Normal file
126
src/runtime/signal_arm.go
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
// Copyright 2009 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.
|
||||
|
||||
// +build darwin dragonfly freebsd linux nacl netbsd openbsd
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func dumpregs(c *sigctxt) {
|
||||
print("trap ", hex(c.trap()), "\n")
|
||||
print("error ", hex(c.error()), "\n")
|
||||
print("oldmask ", hex(c.oldmask()), "\n")
|
||||
print("r0 ", hex(c.r0()), "\n")
|
||||
print("r1 ", hex(c.r1()), "\n")
|
||||
print("r2 ", hex(c.r2()), "\n")
|
||||
print("r3 ", hex(c.r3()), "\n")
|
||||
print("r4 ", hex(c.r4()), "\n")
|
||||
print("r5 ", hex(c.r5()), "\n")
|
||||
print("r6 ", hex(c.r6()), "\n")
|
||||
print("r7 ", hex(c.r7()), "\n")
|
||||
print("r8 ", hex(c.r8()), "\n")
|
||||
print("r9 ", hex(c.r9()), "\n")
|
||||
print("r10 ", hex(c.r10()), "\n")
|
||||
print("fp ", hex(c.fp()), "\n")
|
||||
print("ip ", hex(c.ip()), "\n")
|
||||
print("sp ", hex(c.sp()), "\n")
|
||||
print("lr ", hex(c.lr()), "\n")
|
||||
print("pc ", hex(c.pc()), "\n")
|
||||
print("cpsr ", hex(c.cpsr()), "\n")
|
||||
print("fault ", hex(c.fault()), "\n")
|
||||
}
|
||||
|
||||
func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
|
||||
_g_ := getg()
|
||||
c := &sigctxt{info, ctxt}
|
||||
|
||||
if sig == _SIGPROF {
|
||||
sigprof((*byte)(unsafe.Pointer(uintptr(c.pc()))), (*byte)(unsafe.Pointer(uintptr(c.sp()))), (*byte)(unsafe.Pointer(uintptr(c.lr()))), gp, _g_.m)
|
||||
return
|
||||
}
|
||||
|
||||
flags := int32(_SigThrow)
|
||||
if sig < uint32(len(sigtable)) {
|
||||
flags = sigtable[sig].flags
|
||||
}
|
||||
if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
|
||||
// Make it look like a call to the signal func.
|
||||
// Have to pass arguments out of band since
|
||||
// augmenting the stack frame would break
|
||||
// the unwinding code.
|
||||
gp.sig = sig
|
||||
gp.sigcode0 = uintptr(c.sigcode())
|
||||
gp.sigcode1 = uintptr(c.fault())
|
||||
gp.sigpc = uintptr(c.pc())
|
||||
|
||||
// We arrange lr, and pc to pretend the panicking
|
||||
// function calls sigpanic directly.
|
||||
// Always save LR to stack so that panics in leaf
|
||||
// functions are correctly handled. This smashes
|
||||
// the stack frame but we're not going back there
|
||||
// anyway.
|
||||
sp := c.sp() - 4
|
||||
c.set_sp(sp)
|
||||
*(*uint32)(unsafe.Pointer(uintptr(sp))) = c.lr()
|
||||
|
||||
// Don't bother saving PC if it's zero, which is
|
||||
// probably a call to a nil func: the old link register
|
||||
// is more useful in the stack trace.
|
||||
if gp.sigpc != 0 {
|
||||
c.set_lr(uint32(gp.sigpc))
|
||||
}
|
||||
|
||||
// In case we are panicking from external C code
|
||||
c.set_r10(uint32(uintptr(unsafe.Pointer(gp))))
|
||||
c.set_pc(uint32(funcPC(sigpanic)))
|
||||
return
|
||||
}
|
||||
|
||||
if c.sigcode() == _SI_USER || flags&_SigNotify != 0 {
|
||||
if sigsend(sig) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if flags&_SigKill != 0 {
|
||||
exit(2)
|
||||
}
|
||||
|
||||
if flags&_SigThrow == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
_g_.m.throwing = 1
|
||||
_g_.m.caughtsig = gp
|
||||
startpanic()
|
||||
|
||||
if sig < uint32(len(sigtable)) {
|
||||
print(sigtable[sig].name, "\n")
|
||||
} else {
|
||||
print("Signal ", sig, "\n")
|
||||
}
|
||||
|
||||
print("PC=", hex(c.pc()), "\n")
|
||||
if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
|
||||
print("signal arrived during cgo execution\n")
|
||||
gp = _g_.m.lockedg
|
||||
}
|
||||
print("\n")
|
||||
|
||||
var docrash bool
|
||||
if gotraceback(&docrash) > 0 {
|
||||
goroutineheader(gp)
|
||||
tracebacktrap(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.lr()), gp)
|
||||
tracebackothers(gp)
|
||||
print("\n")
|
||||
dumpregs(c)
|
||||
}
|
||||
|
||||
if docrash {
|
||||
crash()
|
||||
}
|
||||
|
||||
exit(2)
|
||||
}
|
||||
45
src/runtime/signal_darwin.go
Normal file
45
src/runtime/signal_darwin.go
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2009 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
|
||||
|
||||
type sigTabT struct {
|
||||
flags int32
|
||||
name string
|
||||
}
|
||||
|
||||
var sigtable = [...]sigTabT{
|
||||
/* 0 */ {0, "SIGNONE: no trap"},
|
||||
/* 1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
|
||||
/* 2 */ {_SigNotify + _SigKill, "SIGINT: interrupt"},
|
||||
/* 3 */ {_SigNotify + _SigThrow, "SIGQUIT: quit"},
|
||||
/* 4 */ {_SigThrow, "SIGILL: illegal instruction"},
|
||||
/* 5 */ {_SigThrow, "SIGTRAP: trace trap"},
|
||||
/* 6 */ {_SigNotify + _SigThrow, "SIGABRT: abort"},
|
||||
/* 7 */ {_SigThrow, "SIGEMT: emulate instruction executed"},
|
||||
/* 8 */ {_SigPanic, "SIGFPE: floating-point exception"},
|
||||
/* 9 */ {0, "SIGKILL: kill"},
|
||||
/* 10 */ {_SigPanic, "SIGBUS: bus error"},
|
||||
/* 11 */ {_SigPanic, "SIGSEGV: segmentation violation"},
|
||||
/* 12 */ {_SigThrow, "SIGSYS: bad system call"},
|
||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
||||
/* 17 */ {0, "SIGSTOP: stop"},
|
||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {0, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify, "SIGCHLD: child status has changed"},
|
||||
/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
||||
/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
||||
/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
|
||||
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
||||
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
||||
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
||||
/* 27 */ {_SigNotify, "SIGPROF: profiling alarm clock"},
|
||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
||||
/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
|
||||
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||
}
|
||||
34
src/runtime/signal_darwin_386.go
Normal file
34
src/runtime/signal_darwin_386.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2013 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"
|
||||
|
||||
type sigctxt struct {
|
||||
info *siginfo
|
||||
ctxt unsafe.Pointer
|
||||
}
|
||||
|
||||
func (c *sigctxt) regs() *regs32 { return &(*ucontext)(c.ctxt).uc_mcontext.ss }
|
||||
func (c *sigctxt) eax() uint32 { return c.regs().eax }
|
||||
func (c *sigctxt) ebx() uint32 { return c.regs().ebx }
|
||||
func (c *sigctxt) ecx() uint32 { return c.regs().ecx }
|
||||
func (c *sigctxt) edx() uint32 { return c.regs().edx }
|
||||
func (c *sigctxt) edi() uint32 { return c.regs().edi }
|
||||
func (c *sigctxt) esi() uint32 { return c.regs().esi }
|
||||
func (c *sigctxt) ebp() uint32 { return c.regs().ebp }
|
||||
func (c *sigctxt) esp() uint32 { return c.regs().esp }
|
||||
func (c *sigctxt) eip() uint32 { return c.regs().eip }
|
||||
func (c *sigctxt) eflags() uint32 { return c.regs().eflags }
|
||||
func (c *sigctxt) cs() uint32 { return c.regs().cs }
|
||||
func (c *sigctxt) fs() uint32 { return c.regs().fs }
|
||||
func (c *sigctxt) gs() uint32 { return c.regs().gs }
|
||||
func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
|
||||
func (c *sigctxt) sigaddr() uint32 { return uint32(uintptr(unsafe.Pointer(c.info.si_addr))) }
|
||||
|
||||
func (c *sigctxt) set_eip(x uint32) { c.regs().eip = x }
|
||||
func (c *sigctxt) set_esp(x uint32) { c.regs().esp = x }
|
||||
func (c *sigctxt) set_sigcode(x uint32) { c.info.si_code = int32(x) }
|
||||
func (c *sigctxt) set_sigaddr(x uint32) { c.info.si_addr = (*byte)(unsafe.Pointer(uintptr(x))) }
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
#define SIG_REGS(ctxt) (((Ucontext*)(ctxt))->uc_mcontext->ss)
|
||||
|
||||
#define SIG_EAX(info, ctxt) (SIG_REGS(ctxt).eax)
|
||||
#define SIG_EBX(info, ctxt) (SIG_REGS(ctxt).ebx)
|
||||
#define SIG_ECX(info, ctxt) (SIG_REGS(ctxt).ecx)
|
||||
#define SIG_EDX(info, ctxt) (SIG_REGS(ctxt).edx)
|
||||
#define SIG_EDI(info, ctxt) (SIG_REGS(ctxt).edi)
|
||||
#define SIG_ESI(info, ctxt) (SIG_REGS(ctxt).esi)
|
||||
#define SIG_EBP(info, ctxt) (SIG_REGS(ctxt).ebp)
|
||||
#define SIG_ESP(info, ctxt) (SIG_REGS(ctxt).esp)
|
||||
#define SIG_EIP(info, ctxt) (SIG_REGS(ctxt).eip)
|
||||
#define SIG_EFLAGS(info, ctxt) (SIG_REGS(ctxt).eflags)
|
||||
|
||||
#define SIG_CS(info, ctxt) (SIG_REGS(ctxt).cs)
|
||||
#define SIG_FS(info, ctxt) (SIG_REGS(ctxt).fs)
|
||||
#define SIG_GS(info, ctxt) (SIG_REGS(ctxt).gs)
|
||||
|
||||
#define SIG_CODE0(info, ctxt) ((info)->si_code)
|
||||
#define SIG_CODE1(info, ctxt) ((uintptr)(info)->si_addr)
|
||||
42
src/runtime/signal_darwin_amd64.go
Normal file
42
src/runtime/signal_darwin_amd64.go
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2013 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"
|
||||
|
||||
type sigctxt struct {
|
||||
info *siginfo
|
||||
ctxt unsafe.Pointer
|
||||
}
|
||||
|
||||
func (c *sigctxt) regs() *regs64 { return &(*ucontext)(c.ctxt).uc_mcontext.ss }
|
||||
func (c *sigctxt) rax() uint64 { return c.regs().rax }
|
||||
func (c *sigctxt) rbx() uint64 { return c.regs().rbx }
|
||||
func (c *sigctxt) rcx() uint64 { return c.regs().rcx }
|
||||
func (c *sigctxt) rdx() uint64 { return c.regs().rdx }
|
||||
func (c *sigctxt) rdi() uint64 { return c.regs().rdi }
|
||||
func (c *sigctxt) rsi() uint64 { return c.regs().rsi }
|
||||
func (c *sigctxt) rbp() uint64 { return c.regs().rbp }
|
||||
func (c *sigctxt) rsp() uint64 { return c.regs().rsp }
|
||||
func (c *sigctxt) r8() uint64 { return c.regs().r8 }
|
||||
func (c *sigctxt) r9() uint64 { return c.regs().r9 }
|
||||
func (c *sigctxt) r10() uint64 { return c.regs().r10 }
|
||||
func (c *sigctxt) r11() uint64 { return c.regs().r11 }
|
||||
func (c *sigctxt) r12() uint64 { return c.regs().r12 }
|
||||
func (c *sigctxt) r13() uint64 { return c.regs().r13 }
|
||||
func (c *sigctxt) r14() uint64 { return c.regs().r14 }
|
||||
func (c *sigctxt) r15() uint64 { return c.regs().r15 }
|
||||
func (c *sigctxt) rip() uint64 { return c.regs().rip }
|
||||
func (c *sigctxt) rflags() uint64 { return c.regs().rflags }
|
||||
func (c *sigctxt) cs() uint64 { return c.regs().cs }
|
||||
func (c *sigctxt) fs() uint64 { return c.regs().fs }
|
||||
func (c *sigctxt) gs() uint64 { return c.regs().gs }
|
||||
func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) }
|
||||
func (c *sigctxt) sigaddr() uint64 { return uint64(uintptr(unsafe.Pointer(c.info.si_addr))) }
|
||||
|
||||
func (c *sigctxt) set_rip(x uint64) { c.regs().rip = x }
|
||||
func (c *sigctxt) set_rsp(x uint64) { c.regs().rsp = x }
|
||||
func (c *sigctxt) set_sigcode(x uint64) { c.info.si_code = int32(x) }
|
||||
func (c *sigctxt) set_sigaddr(x uint64) { c.info.si_addr = (*byte)(unsafe.Pointer(uintptr(x))) }
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
#define SIG_REGS(ctxt) (((Ucontext*)(ctxt))->uc_mcontext->ss)
|
||||
|
||||
#define SIG_RAX(info, ctxt) (SIG_REGS(ctxt).rax)
|
||||
#define SIG_RBX(info, ctxt) (SIG_REGS(ctxt).rbx)
|
||||
#define SIG_RCX(info, ctxt) (SIG_REGS(ctxt).rcx)
|
||||
#define SIG_RDX(info, ctxt) (SIG_REGS(ctxt).rdx)
|
||||
#define SIG_RDI(info, ctxt) (SIG_REGS(ctxt).rdi)
|
||||
#define SIG_RSI(info, ctxt) (SIG_REGS(ctxt).rsi)
|
||||
#define SIG_RBP(info, ctxt) (SIG_REGS(ctxt).rbp)
|
||||
#define SIG_RSP(info, ctxt) (SIG_REGS(ctxt).rsp)
|
||||
#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).r8)
|
||||
#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).r9)
|
||||
#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).r10)
|
||||
#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).r11)
|
||||
#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).r12)
|
||||
#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).r13)
|
||||
#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).r14)
|
||||
#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).r15)
|
||||
#define SIG_RIP(info, ctxt) (SIG_REGS(ctxt).rip)
|
||||
#define SIG_RFLAGS(info, ctxt) (SIG_REGS(ctxt).rflags)
|
||||
|
||||
#define SIG_CS(info, ctxt) (SIG_REGS(ctxt).cs)
|
||||
#define SIG_FS(info, ctxt) (SIG_REGS(ctxt).fs)
|
||||
#define SIG_GS(info, ctxt) (SIG_REGS(ctxt).gs)
|
||||
|
||||
#define SIG_CODE0(info, ctxt) ((info)->si_code)
|
||||
#define SIG_CODE1(info, ctxt) ((uintptr)(info)->si_addr)
|
||||
78
src/runtime/signal_linux.go
Normal file
78
src/runtime/signal_linux.go
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright 2009 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
|
||||
|
||||
type sigTabT struct {
|
||||
flags int32
|
||||
name string
|
||||
}
|
||||
|
||||
var sigtable = [...]sigTabT{
|
||||
/* 0 */ {0, "SIGNONE: no trap"},
|
||||
/* 1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
|
||||
/* 2 */ {_SigNotify + _SigKill, "SIGINT: interrupt"},
|
||||
/* 3 */ {_SigNotify + _SigThrow, "SIGQUIT: quit"},
|
||||
/* 4 */ {_SigThrow, "SIGILL: illegal instruction"},
|
||||
/* 5 */ {_SigThrow, "SIGTRAP: trace trap"},
|
||||
/* 6 */ {_SigNotify + _SigThrow, "SIGABRT: abort"},
|
||||
/* 7 */ {_SigPanic, "SIGBUS: bus error"},
|
||||
/* 8 */ {_SigPanic, "SIGFPE: floating-point exception"},
|
||||
/* 9 */ {0, "SIGKILL: kill"},
|
||||
/* 10 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||
/* 11 */ {_SigPanic, "SIGSEGV: segmentation violation"},
|
||||
/* 12 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||
/* 16 */ {_SigThrow, "SIGSTKFLT: stack fault"},
|
||||
/* 17 */ {_SigNotify, "SIGCHLD: child status has changed"},
|
||||
/* 18 */ {0, "SIGCONT: continue"},
|
||||
/* 19 */ {0, "SIGSTOP: stop, unblockable"},
|
||||
/* 20 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
||||
/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
||||
/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
||||
/* 23 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
||||
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
||||
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
||||
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
||||
/* 27 */ {_SigNotify, "SIGPROF: profiling alarm clock"},
|
||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
||||
/* 29 */ {_SigNotify, "SIGIO: i/o now possible"},
|
||||
/* 30 */ {_SigNotify, "SIGPWR: power failure restart"},
|
||||
/* 31 */ {_SigNotify, "SIGSYS: bad system call"},
|
||||
/* 32 */ {0, "signal 32"}, /* SIGCANCEL; see issue 6997 */
|
||||
/* 33 */ {0, "signal 33"}, /* SIGSETXID; see issue 3871 */
|
||||
/* 34 */ {_SigNotify, "signal 34"},
|
||||
/* 35 */ {_SigNotify, "signal 35"},
|
||||
/* 36 */ {_SigNotify, "signal 36"},
|
||||
/* 37 */ {_SigNotify, "signal 37"},
|
||||
/* 38 */ {_SigNotify, "signal 38"},
|
||||
/* 39 */ {_SigNotify, "signal 39"},
|
||||
/* 40 */ {_SigNotify, "signal 40"},
|
||||
/* 41 */ {_SigNotify, "signal 41"},
|
||||
/* 42 */ {_SigNotify, "signal 42"},
|
||||
/* 43 */ {_SigNotify, "signal 43"},
|
||||
/* 44 */ {_SigNotify, "signal 44"},
|
||||
/* 45 */ {_SigNotify, "signal 45"},
|
||||
/* 46 */ {_SigNotify, "signal 46"},
|
||||
/* 47 */ {_SigNotify, "signal 47"},
|
||||
/* 48 */ {_SigNotify, "signal 48"},
|
||||
/* 49 */ {_SigNotify, "signal 49"},
|
||||
/* 50 */ {_SigNotify, "signal 50"},
|
||||
/* 51 */ {_SigNotify, "signal 51"},
|
||||
/* 52 */ {_SigNotify, "signal 52"},
|
||||
/* 53 */ {_SigNotify, "signal 53"},
|
||||
/* 54 */ {_SigNotify, "signal 54"},
|
||||
/* 55 */ {_SigNotify, "signal 55"},
|
||||
/* 56 */ {_SigNotify, "signal 56"},
|
||||
/* 57 */ {_SigNotify, "signal 57"},
|
||||
/* 58 */ {_SigNotify, "signal 58"},
|
||||
/* 59 */ {_SigNotify, "signal 59"},
|
||||
/* 60 */ {_SigNotify, "signal 60"},
|
||||
/* 61 */ {_SigNotify, "signal 61"},
|
||||
/* 62 */ {_SigNotify, "signal 62"},
|
||||
/* 63 */ {_SigNotify, "signal 63"},
|
||||
/* 64 */ {_SigNotify, "signal 64"},
|
||||
}
|
||||
36
src/runtime/signal_linux_386.go
Normal file
36
src/runtime/signal_linux_386.go
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2013 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"
|
||||
|
||||
type sigctxt struct {
|
||||
info *siginfo
|
||||
ctxt unsafe.Pointer
|
||||
}
|
||||
|
||||
func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext }
|
||||
func (c *sigctxt) eax() uint32 { return c.regs().eax }
|
||||
func (c *sigctxt) ebx() uint32 { return c.regs().ebx }
|
||||
func (c *sigctxt) ecx() uint32 { return c.regs().ecx }
|
||||
func (c *sigctxt) edx() uint32 { return c.regs().edx }
|
||||
func (c *sigctxt) edi() uint32 { return c.regs().edi }
|
||||
func (c *sigctxt) esi() uint32 { return c.regs().esi }
|
||||
func (c *sigctxt) ebp() uint32 { return c.regs().ebp }
|
||||
func (c *sigctxt) esp() uint32 { return c.regs().esp }
|
||||
func (c *sigctxt) eip() uint32 { return c.regs().eip }
|
||||
func (c *sigctxt) eflags() uint32 { return c.regs().eflags }
|
||||
func (c *sigctxt) cs() uint32 { return uint32(c.regs().cs) }
|
||||
func (c *sigctxt) fs() uint32 { return uint32(c.regs().fs) }
|
||||
func (c *sigctxt) gs() uint32 { return uint32(c.regs().gs) }
|
||||
func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
|
||||
func (c *sigctxt) sigaddr() uint32 { return uint32(*(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize))) }
|
||||
|
||||
func (c *sigctxt) set_eip(x uint32) { c.regs().eip = x }
|
||||
func (c *sigctxt) set_esp(x uint32) { c.regs().esp = x }
|
||||
func (c *sigctxt) set_sigcode(x uint32) { c.info.si_code = int32(x) }
|
||||
func (c *sigctxt) set_sigaddr(x uint32) {
|
||||
*(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize)) = uintptr(x)
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
#define SIG_REGS(ctxt) (*((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext))
|
||||
|
||||
#define SIG_EAX(info, ctxt) (SIG_REGS(ctxt).eax)
|
||||
#define SIG_EBX(info, ctxt) (SIG_REGS(ctxt).ebx)
|
||||
#define SIG_ECX(info, ctxt) (SIG_REGS(ctxt).ecx)
|
||||
#define SIG_EDX(info, ctxt) (SIG_REGS(ctxt).edx)
|
||||
#define SIG_EDI(info, ctxt) (SIG_REGS(ctxt).edi)
|
||||
#define SIG_ESI(info, ctxt) (SIG_REGS(ctxt).esi)
|
||||
#define SIG_EBP(info, ctxt) (SIG_REGS(ctxt).ebp)
|
||||
#define SIG_ESP(info, ctxt) (SIG_REGS(ctxt).esp)
|
||||
#define SIG_EIP(info, ctxt) (SIG_REGS(ctxt).eip)
|
||||
#define SIG_EFLAGS(info, ctxt) (SIG_REGS(ctxt).eflags)
|
||||
|
||||
#define SIG_CS(info, ctxt) (SIG_REGS(ctxt).cs)
|
||||
#define SIG_FS(info, ctxt) (SIG_REGS(ctxt).fs)
|
||||
#define SIG_GS(info, ctxt) (SIG_REGS(ctxt).gs)
|
||||
|
||||
#define SIG_CODE0(info, ctxt) ((info)->si_code)
|
||||
#define SIG_CODE1(info, ctxt) (((uintptr*)(info))[2])
|
||||
|
||||
46
src/runtime/signal_linux_amd64.go
Normal file
46
src/runtime/signal_linux_amd64.go
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2013 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"
|
||||
|
||||
type sigctxt struct {
|
||||
info *siginfo
|
||||
ctxt unsafe.Pointer
|
||||
}
|
||||
|
||||
func (c *sigctxt) regs() *sigcontext {
|
||||
return (*sigcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext))
|
||||
}
|
||||
func (c *sigctxt) rax() uint64 { return c.regs().rax }
|
||||
func (c *sigctxt) rbx() uint64 { return c.regs().rbx }
|
||||
func (c *sigctxt) rcx() uint64 { return c.regs().rcx }
|
||||
func (c *sigctxt) rdx() uint64 { return c.regs().rdx }
|
||||
func (c *sigctxt) rdi() uint64 { return c.regs().rdi }
|
||||
func (c *sigctxt) rsi() uint64 { return c.regs().rsi }
|
||||
func (c *sigctxt) rbp() uint64 { return c.regs().rbp }
|
||||
func (c *sigctxt) rsp() uint64 { return c.regs().rsp }
|
||||
func (c *sigctxt) r8() uint64 { return c.regs().r8 }
|
||||
func (c *sigctxt) r9() uint64 { return c.regs().r9 }
|
||||
func (c *sigctxt) r10() uint64 { return c.regs().r10 }
|
||||
func (c *sigctxt) r11() uint64 { return c.regs().r11 }
|
||||
func (c *sigctxt) r12() uint64 { return c.regs().r12 }
|
||||
func (c *sigctxt) r13() uint64 { return c.regs().r13 }
|
||||
func (c *sigctxt) r14() uint64 { return c.regs().r14 }
|
||||
func (c *sigctxt) r15() uint64 { return c.regs().r15 }
|
||||
func (c *sigctxt) rip() uint64 { return c.regs().rip }
|
||||
func (c *sigctxt) rflags() uint64 { return c.regs().eflags }
|
||||
func (c *sigctxt) cs() uint64 { return uint64(c.regs().cs) }
|
||||
func (c *sigctxt) fs() uint64 { return uint64(c.regs().fs) }
|
||||
func (c *sigctxt) gs() uint64 { return uint64(c.regs().gs) }
|
||||
func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) }
|
||||
func (c *sigctxt) sigaddr() uint64 { return uint64(*(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize))) }
|
||||
|
||||
func (c *sigctxt) set_rip(x uint64) { c.regs().rip = x }
|
||||
func (c *sigctxt) set_rsp(x uint64) { c.regs().rsp = x }
|
||||
func (c *sigctxt) set_sigcode(x uint64) { c.info.si_code = int32(x) }
|
||||
func (c *sigctxt) set_sigaddr(x uint64) {
|
||||
*(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize)) = uintptr(x)
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
#define SIG_REGS(ctxt) (*((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext))
|
||||
|
||||
#define SIG_RAX(info, ctxt) (SIG_REGS(ctxt).rax)
|
||||
#define SIG_RBX(info, ctxt) (SIG_REGS(ctxt).rbx)
|
||||
#define SIG_RCX(info, ctxt) (SIG_REGS(ctxt).rcx)
|
||||
#define SIG_RDX(info, ctxt) (SIG_REGS(ctxt).rdx)
|
||||
#define SIG_RDI(info, ctxt) (SIG_REGS(ctxt).rdi)
|
||||
#define SIG_RSI(info, ctxt) (SIG_REGS(ctxt).rsi)
|
||||
#define SIG_RBP(info, ctxt) (SIG_REGS(ctxt).rbp)
|
||||
#define SIG_RSP(info, ctxt) (SIG_REGS(ctxt).rsp)
|
||||
#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).r8)
|
||||
#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).r9)
|
||||
#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).r10)
|
||||
#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).r11)
|
||||
#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).r12)
|
||||
#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).r13)
|
||||
#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).r14)
|
||||
#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).r15)
|
||||
#define SIG_RIP(info, ctxt) (SIG_REGS(ctxt).rip)
|
||||
#define SIG_RFLAGS(info, ctxt) ((uint64)SIG_REGS(ctxt).eflags)
|
||||
|
||||
#define SIG_CS(info, ctxt) ((uint64)SIG_REGS(ctxt).cs)
|
||||
#define SIG_FS(info, ctxt) ((uint64)SIG_REGS(ctxt).fs)
|
||||
#define SIG_GS(info, ctxt) ((uint64)SIG_REGS(ctxt).gs)
|
||||
|
||||
#define SIG_CODE0(info, ctxt) ((info)->si_code)
|
||||
#define SIG_CODE1(info, ctxt) (((uintptr*)(info))[2])
|
||||
|
||||
48
src/runtime/signal_linux_arm.go
Normal file
48
src/runtime/signal_linux_arm.go
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2013 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"
|
||||
|
||||
type sigctxt struct {
|
||||
info *siginfo
|
||||
ctxt unsafe.Pointer
|
||||
}
|
||||
|
||||
func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext }
|
||||
func (c *sigctxt) r0() uint32 { return c.regs().r0 }
|
||||
func (c *sigctxt) r1() uint32 { return c.regs().r1 }
|
||||
func (c *sigctxt) r2() uint32 { return c.regs().r2 }
|
||||
func (c *sigctxt) r3() uint32 { return c.regs().r3 }
|
||||
func (c *sigctxt) r4() uint32 { return c.regs().r4 }
|
||||
func (c *sigctxt) r5() uint32 { return c.regs().r5 }
|
||||
func (c *sigctxt) r6() uint32 { return c.regs().r6 }
|
||||
func (c *sigctxt) r7() uint32 { return c.regs().r7 }
|
||||
func (c *sigctxt) r8() uint32 { return c.regs().r8 }
|
||||
func (c *sigctxt) r9() uint32 { return c.regs().r9 }
|
||||
func (c *sigctxt) r10() uint32 { return c.regs().r10 }
|
||||
func (c *sigctxt) fp() uint32 { return c.regs().fp }
|
||||
func (c *sigctxt) ip() uint32 { return c.regs().ip }
|
||||
func (c *sigctxt) sp() uint32 { return c.regs().sp }
|
||||
func (c *sigctxt) lr() uint32 { return c.regs().lr }
|
||||
func (c *sigctxt) pc() uint32 { return c.regs().pc }
|
||||
func (c *sigctxt) cpsr() uint32 { return c.regs().cpsr }
|
||||
func (c *sigctxt) fault() uint32 { return c.regs().fault_address }
|
||||
func (c *sigctxt) trap() uint32 { return c.regs().trap_no }
|
||||
func (c *sigctxt) error() uint32 { return c.regs().error_code }
|
||||
func (c *sigctxt) oldmask() uint32 { return c.regs().oldmask }
|
||||
|
||||
func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
|
||||
func (c *sigctxt) sigaddr() uint32 { return uint32(*(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize))) }
|
||||
|
||||
func (c *sigctxt) set_pc(x uint32) { c.regs().pc = x }
|
||||
func (c *sigctxt) set_sp(x uint32) { c.regs().sp = x }
|
||||
func (c *sigctxt) set_lr(x uint32) { c.regs().lr = x }
|
||||
func (c *sigctxt) set_r10(x uint32) { c.regs().r10 = x }
|
||||
|
||||
func (c *sigctxt) set_sigcode(x uint32) { c.info.si_code = int32(x) }
|
||||
func (c *sigctxt) set_sigaddr(x uint32) {
|
||||
*(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize)) = uintptr(x)
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
#define SIG_REGS(ctxt) (*((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext))
|
||||
|
||||
#define SIG_R0(info, ctxt) (SIG_REGS(ctxt).arm_r0)
|
||||
#define SIG_R1(info, ctxt) (SIG_REGS(ctxt).arm_r1)
|
||||
#define SIG_R2(info, ctxt) (SIG_REGS(ctxt).arm_r2)
|
||||
#define SIG_R3(info, ctxt) (SIG_REGS(ctxt).arm_r3)
|
||||
#define SIG_R4(info, ctxt) (SIG_REGS(ctxt).arm_r4)
|
||||
#define SIG_R5(info, ctxt) (SIG_REGS(ctxt).arm_r5)
|
||||
#define SIG_R6(info, ctxt) (SIG_REGS(ctxt).arm_r6)
|
||||
#define SIG_R7(info, ctxt) (SIG_REGS(ctxt).arm_r7)
|
||||
#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).arm_r8)
|
||||
#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).arm_r9)
|
||||
#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).arm_r10)
|
||||
#define SIG_FP(info, ctxt) (SIG_REGS(ctxt).arm_fp)
|
||||
#define SIG_IP(info, ctxt) (SIG_REGS(ctxt).arm_ip)
|
||||
#define SIG_SP(info, ctxt) (SIG_REGS(ctxt).arm_sp)
|
||||
#define SIG_LR(info, ctxt) (SIG_REGS(ctxt).arm_lr)
|
||||
#define SIG_PC(info, ctxt) (SIG_REGS(ctxt).arm_pc)
|
||||
#define SIG_CPSR(info, ctxt) (SIG_REGS(ctxt).arm_cpsr)
|
||||
#define SIG_FAULT(info, ctxt) (SIG_REGS(ctxt).fault_address)
|
||||
#define SIG_TRAP(info, ctxt) (SIG_REGS(ctxt).trap_no)
|
||||
#define SIG_ERROR(info, ctxt) (SIG_REGS(ctxt).error_code)
|
||||
#define SIG_OLDMASK(info, ctxt) (SIG_REGS(ctxt).oldmask)
|
||||
#define SIG_CODE0(info, ctxt) ((uintptr)(info)->si_code)
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
#include "runtime.h"
|
||||
#include "defs_GOOS_GOARCH.h"
|
||||
#include "os_GOOS.h"
|
||||
#include "signal_unix.h"
|
||||
|
||||
extern SigTab runtime·sigtab[];
|
||||
|
||||
void
|
||||
runtime·initsig(void)
|
||||
{
|
||||
int32 i;
|
||||
SigTab *t;
|
||||
|
||||
// First call: basic setup.
|
||||
for(i = 0; i<NSIG; i++) {
|
||||
t = &runtime·sigtab[i];
|
||||
if((t->flags == 0) || (t->flags & SigDefault))
|
||||
continue;
|
||||
|
||||
// For some signals, we respect an inherited SIG_IGN handler
|
||||
// rather than insist on installing our own default handler.
|
||||
// Even these signals can be fetched using the os/signal package.
|
||||
switch(i) {
|
||||
case SIGHUP:
|
||||
case SIGINT:
|
||||
if(runtime·getsig(i) == SIG_IGN) {
|
||||
t->flags = SigNotify | SigIgnored;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
t->flags |= SigHandling;
|
||||
runtime·setsig(i, runtime·sighandler, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
runtime·sigenable(uint32 sig)
|
||||
{
|
||||
SigTab *t;
|
||||
|
||||
if(sig >= NSIG)
|
||||
return;
|
||||
|
||||
t = &runtime·sigtab[sig];
|
||||
if((t->flags & SigNotify) && !(t->flags & SigHandling)) {
|
||||
t->flags |= SigHandling;
|
||||
if(runtime·getsig(sig) == SIG_IGN)
|
||||
t->flags |= SigIgnored;
|
||||
runtime·setsig(sig, runtime·sighandler, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
runtime·sigdisable(uint32 sig)
|
||||
{
|
||||
SigTab *t;
|
||||
|
||||
if(sig >= NSIG)
|
||||
return;
|
||||
|
||||
t = &runtime·sigtab[sig];
|
||||
if((t->flags & SigNotify) && (t->flags & SigHandling)) {
|
||||
t->flags &= ~SigHandling;
|
||||
if(t->flags & SigIgnored)
|
||||
runtime·setsig(sig, SIG_IGN, true);
|
||||
else
|
||||
runtime·setsig(sig, SIG_DFL, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
runtime·resetcpuprofiler(int32 hz)
|
||||
{
|
||||
Itimerval it;
|
||||
|
||||
runtime·memclr((byte*)&it, sizeof it);
|
||||
if(hz == 0) {
|
||||
runtime·setitimer(ITIMER_PROF, &it, nil);
|
||||
} else {
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_interval.tv_usec = 1000000 / hz;
|
||||
it.it_value = it.it_interval;
|
||||
runtime·setitimer(ITIMER_PROF, &it, nil);
|
||||
}
|
||||
g->m->profilehz = hz;
|
||||
}
|
||||
|
||||
void
|
||||
runtime·sigpipe(void)
|
||||
{
|
||||
runtime·setsig(SIGPIPE, SIG_DFL, false);
|
||||
runtime·raise(SIGPIPE);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·crash(void)
|
||||
{
|
||||
#ifdef GOOS_darwin
|
||||
// OS X core dumps are linear dumps of the mapped memory,
|
||||
// from the first virtual byte to the last, with zeros in the gaps.
|
||||
// Because of the way we arrange the address space on 64-bit systems,
|
||||
// this means the OS X core file will be >128 GB and even on a zippy
|
||||
// workstation can take OS X well over an hour to write (uninterruptible).
|
||||
// Save users from making that mistake.
|
||||
if(sizeof(void*) == 8)
|
||||
return;
|
||||
#endif
|
||||
|
||||
runtime·unblocksignals();
|
||||
runtime·setsig(SIGABRT, SIG_DFL, false);
|
||||
runtime·raise(SIGABRT);
|
||||
}
|
||||
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
package runtime
|
||||
|
||||
func sigpipe()
|
||||
|
||||
func os_sigpipe() {
|
||||
onM(sigpipe)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
// Copyright 2009 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.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#define N SigNotify
|
||||
#define K SigKill
|
||||
#define T SigThrow
|
||||
#define P SigPanic
|
||||
#define D SigDefault
|
||||
|
||||
#pragma dataflag NOPTR
|
||||
SigTab runtime·sigtab[] = {
|
||||
/* 0 */ 0, "SIGNONE: no trap",
|
||||
/* 1 */ N+K, "SIGHUP: terminal line hangup",
|
||||
/* 2 */ N+K, "SIGINT: interrupt",
|
||||
/* 3 */ N+T, "SIGQUIT: quit",
|
||||
/* 4 */ T, "SIGILL: illegal instruction",
|
||||
/* 5 */ T, "SIGTRAP: trace trap",
|
||||
/* 6 */ N+T, "SIGABRT: abort",
|
||||
/* 7 */ T, "SIGEMT: emulate instruction executed",
|
||||
/* 8 */ P, "SIGFPE: floating-point exception",
|
||||
/* 9 */ 0, "SIGKILL: kill",
|
||||
/* 10 */ P, "SIGBUS: bus error",
|
||||
/* 11 */ P, "SIGSEGV: segmentation violation",
|
||||
/* 12 */ T, "SIGSYS: bad system call",
|
||||
/* 13 */ N, "SIGPIPE: write to broken pipe",
|
||||
/* 14 */ N, "SIGALRM: alarm clock",
|
||||
/* 15 */ N+K, "SIGTERM: termination",
|
||||
/* 16 */ N, "SIGURG: urgent condition on socket",
|
||||
/* 17 */ 0, "SIGSTOP: stop",
|
||||
/* 18 */ N+D, "SIGTSTP: keyboard stop",
|
||||
/* 19 */ 0, "SIGCONT: continue after stop",
|
||||
/* 20 */ N, "SIGCHLD: child status has changed",
|
||||
/* 21 */ N+D, "SIGTTIN: background read from tty",
|
||||
/* 22 */ N+D, "SIGTTOU: background write to tty",
|
||||
/* 23 */ N, "SIGIO: i/o now possible",
|
||||
/* 24 */ N, "SIGXCPU: cpu limit exceeded",
|
||||
/* 25 */ N, "SIGXFSZ: file size limit exceeded",
|
||||
/* 26 */ N, "SIGVTALRM: virtual alarm clock",
|
||||
/* 27 */ N, "SIGPROF: profiling alarm clock",
|
||||
/* 28 */ N, "SIGWINCH: window size change",
|
||||
/* 29 */ N, "SIGINFO: status request from keyboard",
|
||||
/* 30 */ N, "SIGUSR1: user-defined signal 1",
|
||||
/* 31 */ N, "SIGUSR2: user-defined signal 2",
|
||||
};
|
||||
|
||||
#undef N
|
||||
#undef K
|
||||
#undef T
|
||||
#undef P
|
||||
#undef D
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
// Copyright 2009 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.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#define N SigNotify
|
||||
#define K SigKill
|
||||
#define T SigThrow
|
||||
#define P SigPanic
|
||||
#define D SigDefault
|
||||
|
||||
#pragma dataflag NOPTR
|
||||
SigTab runtime·sigtab[] = {
|
||||
/* 0 */ 0, "SIGNONE: no trap",
|
||||
/* 1 */ N+K, "SIGHUP: terminal line hangup",
|
||||
/* 2 */ N+K, "SIGINT: interrupt",
|
||||
/* 3 */ N+T, "SIGQUIT: quit",
|
||||
/* 4 */ T, "SIGILL: illegal instruction",
|
||||
/* 5 */ T, "SIGTRAP: trace trap",
|
||||
/* 6 */ N+T, "SIGABRT: abort",
|
||||
/* 7 */ P, "SIGBUS: bus error",
|
||||
/* 8 */ P, "SIGFPE: floating-point exception",
|
||||
/* 9 */ 0, "SIGKILL: kill",
|
||||
/* 10 */ N, "SIGUSR1: user-defined signal 1",
|
||||
/* 11 */ P, "SIGSEGV: segmentation violation",
|
||||
/* 12 */ N, "SIGUSR2: user-defined signal 2",
|
||||
/* 13 */ N, "SIGPIPE: write to broken pipe",
|
||||
/* 14 */ N, "SIGALRM: alarm clock",
|
||||
/* 15 */ N+K, "SIGTERM: termination",
|
||||
/* 16 */ T, "SIGSTKFLT: stack fault",
|
||||
/* 17 */ N, "SIGCHLD: child status has changed",
|
||||
/* 18 */ 0, "SIGCONT: continue",
|
||||
/* 19 */ 0, "SIGSTOP: stop, unblockable",
|
||||
/* 20 */ N+D, "SIGTSTP: keyboard stop",
|
||||
/* 21 */ N+D, "SIGTTIN: background read from tty",
|
||||
/* 22 */ N+D, "SIGTTOU: background write to tty",
|
||||
/* 23 */ N, "SIGURG: urgent condition on socket",
|
||||
/* 24 */ N, "SIGXCPU: cpu limit exceeded",
|
||||
/* 25 */ N, "SIGXFSZ: file size limit exceeded",
|
||||
/* 26 */ N, "SIGVTALRM: virtual alarm clock",
|
||||
/* 27 */ N, "SIGPROF: profiling alarm clock",
|
||||
/* 28 */ N, "SIGWINCH: window size change",
|
||||
/* 29 */ N, "SIGIO: i/o now possible",
|
||||
/* 30 */ N, "SIGPWR: power failure restart",
|
||||
/* 31 */ N, "SIGSYS: bad system call",
|
||||
/* 32 */ 0, "signal 32", /* SIGCANCEL; see issue 6997 */
|
||||
/* 33 */ 0, "signal 33", /* SIGSETXID; see issue 3871 */
|
||||
/* 34 */ N, "signal 34",
|
||||
/* 35 */ N, "signal 35",
|
||||
/* 36 */ N, "signal 36",
|
||||
/* 37 */ N, "signal 37",
|
||||
/* 38 */ N, "signal 38",
|
||||
/* 39 */ N, "signal 39",
|
||||
/* 40 */ N, "signal 40",
|
||||
/* 41 */ N, "signal 41",
|
||||
/* 42 */ N, "signal 42",
|
||||
/* 43 */ N, "signal 43",
|
||||
/* 44 */ N, "signal 44",
|
||||
/* 45 */ N, "signal 45",
|
||||
/* 46 */ N, "signal 46",
|
||||
/* 47 */ N, "signal 47",
|
||||
/* 48 */ N, "signal 48",
|
||||
/* 49 */ N, "signal 49",
|
||||
/* 50 */ N, "signal 50",
|
||||
/* 51 */ N, "signal 51",
|
||||
/* 52 */ N, "signal 52",
|
||||
/* 53 */ N, "signal 53",
|
||||
/* 54 */ N, "signal 54",
|
||||
/* 55 */ N, "signal 55",
|
||||
/* 56 */ N, "signal 56",
|
||||
/* 57 */ N, "signal 57",
|
||||
/* 58 */ N, "signal 58",
|
||||
/* 59 */ N, "signal 59",
|
||||
/* 60 */ N, "signal 60",
|
||||
/* 61 */ N, "signal 61",
|
||||
/* 62 */ N, "signal 62",
|
||||
/* 63 */ N, "signal 63",
|
||||
/* 64 */ N, "signal 64",
|
||||
};
|
||||
|
||||
#undef N
|
||||
#undef K
|
||||
#undef T
|
||||
#undef P
|
||||
#undef D
|
||||
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
package runtime
|
||||
|
||||
func signame(int32) *byte
|
||||
|
||||
func sigpanic() {
|
||||
g := getg()
|
||||
if !canpanic(g) {
|
||||
|
|
@ -36,5 +34,10 @@ func sigpanic() {
|
|||
}
|
||||
panicfloat()
|
||||
}
|
||||
panic(errorString(gostringnocopy(signame(g.sig))))
|
||||
|
||||
if g.sig >= uint32(len(sigtable)) {
|
||||
// can't happen: we looked up g.sig in sigtable to decide to call sigpanic
|
||||
gothrow("unexpected signal value")
|
||||
}
|
||||
panic(errorString(sigtable[g.sig].name))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ const (
|
|||
|
||||
// Called from sighandler to send a signal back out of the signal handling thread.
|
||||
// Reports whether the signal was sent. If not, the caller typically crashes the program.
|
||||
func sigsend(s int32) bool {
|
||||
func sigsend(s uint32) bool {
|
||||
bit := uint32(1) << uint(s&31)
|
||||
if !sig.inuse || s < 0 || int(s) >= 32*len(sig.wanted) || sig.wanted[s/32]&bit == 0 {
|
||||
return false
|
||||
|
|
@ -157,9 +157,6 @@ func badsignal(sig uintptr) {
|
|||
cgocallback(unsafe.Pointer(funcPC(sigsend)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig))
|
||||
}
|
||||
|
||||
func sigenable_m()
|
||||
func sigdisable_m()
|
||||
|
||||
func sigenable_go(s uint32) {
|
||||
g := getg()
|
||||
g.m.scalararg[0] = uintptr(s)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue