mirror of
https://github.com/golang/go
synced 2024-11-24 22:57:57 -07:00
runtime: if os/signal is not in use, crash on
most signals, so that ordinary programs can be killed, for example. Fixes #434. R=dsymonds1 CC=golang-dev, hoisie https://golang.org/cl/180064
This commit is contained in:
parent
96ee38bfc2
commit
08579c26dd
@ -41,6 +41,7 @@ func process(ch chan<- Signal) {
|
||||
}
|
||||
|
||||
func init() {
|
||||
runtime.Siginit()
|
||||
ch := make(chan Signal) // Done here so Incoming can have type <-chan Signal
|
||||
Incoming = ch
|
||||
go process(ch)
|
||||
|
@ -41,8 +41,9 @@ sighandler(int32 sig, Siginfo *info, void *context)
|
||||
Regs *r;
|
||||
|
||||
if(sigtab[sig].flags & SigQueue) {
|
||||
sigsend(sig);
|
||||
return;
|
||||
if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
|
||||
return;
|
||||
exit(2); // SIGINT, SIGTERM, etc
|
||||
}
|
||||
|
||||
if(panicking) // traceback already printed
|
||||
|
@ -49,8 +49,9 @@ sighandler(int32 sig, Siginfo *info, void *context)
|
||||
Regs *r;
|
||||
|
||||
if(sigtab[sig].flags & SigQueue) {
|
||||
sigsend(sig);
|
||||
return;
|
||||
if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
|
||||
return;
|
||||
exit(2); // SIGINT, SIGTERM, etc
|
||||
}
|
||||
|
||||
if(panicking) // traceback already printed
|
||||
|
@ -22,24 +22,24 @@ static SigTab sigtab[] = {
|
||||
/* 11 */ C, "SIGSEGV: segmentation violation",
|
||||
/* 12 */ C, "SIGSYS: bad system call",
|
||||
/* 13 */ I, "SIGPIPE: write to broken pipe",
|
||||
/* 14 */ Q+R, "SIGALRM: alarm clock",
|
||||
/* 14 */ Q+I+R, "SIGALRM: alarm clock",
|
||||
/* 15 */ Q+R, "SIGTERM: termination",
|
||||
/* 16 */ Q+R, "SIGURG: urgent condition on socket",
|
||||
/* 16 */ Q+I+R, "SIGURG: urgent condition on socket",
|
||||
/* 17 */ 0, "SIGSTOP: stop",
|
||||
/* 18 */ Q+R, "SIGTSTP: keyboard stop",
|
||||
/* 18 */ Q+I+R, "SIGTSTP: keyboard stop",
|
||||
/* 19 */ 0, "SIGCONT: continue after stop",
|
||||
/* 20 */ I+R, "SIGCHLD: child status has changed",
|
||||
/* 21 */ Q+R, "SIGTTIN: background read from tty",
|
||||
/* 22 */ Q+R, "SIGTTOU: background write to tty",
|
||||
/* 23 */ Q+R, "SIGIO: i/o now possible",
|
||||
/* 24 */ Q+R, "SIGXCPU: cpu limit exceeded",
|
||||
/* 25 */ Q+R, "SIGXFSZ: file size limit exceeded",
|
||||
/* 26 */ Q+R, "SIGVTALRM: virtual alarm clock",
|
||||
/* 27 */ Q+R, "SIGPROF: profiling alarm clock",
|
||||
/* 28 */ Q+R, "SIGWINCH: window size change",
|
||||
/* 29 */ Q+R, "SIGINFO: status request from keyboard",
|
||||
/* 30 */ Q+R, "SIGUSR1: user-defined signal 1",
|
||||
/* 31 */ Q+R, "SIGUSR2: user-defined signal 2",
|
||||
/* 21 */ Q+I+R, "SIGTTIN: background read from tty",
|
||||
/* 22 */ Q+I+R, "SIGTTOU: background write to tty",
|
||||
/* 23 */ Q+I+R, "SIGIO: i/o now possible",
|
||||
/* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
|
||||
/* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
|
||||
/* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
|
||||
/* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
|
||||
/* 28 */ Q+I+R, "SIGWINCH: window size change",
|
||||
/* 29 */ Q+I+R, "SIGINFO: status request from keyboard",
|
||||
/* 30 */ Q+I+R, "SIGUSR1: user-defined signal 1",
|
||||
/* 31 */ Q+I+R, "SIGUSR2: user-defined signal 2",
|
||||
};
|
||||
#undef C
|
||||
#undef I
|
||||
|
@ -66,3 +66,7 @@ func Sigrecv() uint32
|
||||
|
||||
// Signame returns a string describing the signal, or "" if the signal is unknown.
|
||||
func Signame(sig int32) string
|
||||
|
||||
// Siginit enables receipt of signals via Sigrecv. It should typically
|
||||
// be called during initialization.
|
||||
func Siginit()
|
||||
|
@ -51,8 +51,9 @@ sighandler(int32 sig, Siginfo* info, void* context)
|
||||
Mcontext *mc;
|
||||
|
||||
if(sigtab[sig].flags & SigQueue) {
|
||||
sigsend(sig);
|
||||
return;
|
||||
if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
|
||||
return;
|
||||
exit(2); // SIGINT, SIGTERM, etc
|
||||
}
|
||||
|
||||
if(panicking) // traceback already printed
|
||||
|
@ -59,8 +59,9 @@ sighandler(int32 sig, Siginfo* info, void* context)
|
||||
Mcontext *mc;
|
||||
|
||||
if(sigtab[sig].flags & SigQueue) {
|
||||
sigsend(sig);
|
||||
return;
|
||||
if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
|
||||
return;
|
||||
exit(2); // SIGINT, SIGTERM, etc
|
||||
}
|
||||
|
||||
if(panicking) // traceback already printed
|
||||
|
@ -22,25 +22,25 @@ static SigTab sigtab[] = {
|
||||
/* 11 */ C, "SIGSEGV: segmentation violation",
|
||||
/* 12 */ C, "SIGSYS: bad system call",
|
||||
/* 13 */ I, "SIGPIPE: write to broken pipe",
|
||||
/* 14 */ Q+R, "SIGALRM: alarm clock",
|
||||
/* 14 */ Q+I+R, "SIGALRM: alarm clock",
|
||||
/* 15 */ Q+R, "SIGTERM: termination",
|
||||
/* 16 */ Q+R, "SIGURG: urgent condition on socket",
|
||||
/* 16 */ Q+I+R, "SIGURG: urgent condition on socket",
|
||||
/* 17 */ 0, "SIGSTOP: stop, unblockable",
|
||||
/* 18 */ Q+R, "SIGTSTP: stop from tty",
|
||||
/* 18 */ Q+I+R, "SIGTSTP: stop from tty",
|
||||
/* 19 */ 0, "SIGCONT: continue",
|
||||
/* 20 */ I+R, "SIGCHLD: child status has changed",
|
||||
/* 21 */ Q+R, "SIGTTIN: background read from tty",
|
||||
/* 22 */ Q+R, "SIGTTOU: background write to tty",
|
||||
/* 23 */ Q+R, "SIGIO: i/o now possible",
|
||||
/* 24 */ Q+R, "SIGXCPU: cpu limit exceeded",
|
||||
/* 25 */ Q+R, "SIGXFSZ: file size limit exceeded",
|
||||
/* 26 */ Q+R, "SIGVTALRM: virtual alarm clock",
|
||||
/* 27 */ Q+R, "SIGPROF: profiling alarm clock",
|
||||
/* 28 */ I+R, "SIGWINCH: window size change",
|
||||
/* 29 */ Q+R, "SIGINFO: information request",
|
||||
/* 30 */ Q+R, "SIGUSR1: user-defined signal 1",
|
||||
/* 31 */ Q+R, "SIGUSR2: user-defined signal 2",
|
||||
/* 32 */ Q+R, "SIGTHR: reserved",
|
||||
/* 21 */ Q+I+R, "SIGTTIN: background read from tty",
|
||||
/* 22 */ Q+I+R, "SIGTTOU: background write to tty",
|
||||
/* 23 */ Q+I+R, "SIGIO: i/o now possible",
|
||||
/* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
|
||||
/* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
|
||||
/* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
|
||||
/* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
|
||||
/* 28 */ Q+I+R, "SIGWINCH: window size change",
|
||||
/* 29 */ Q+I+R, "SIGINFO: information request",
|
||||
/* 30 */ Q+I+R, "SIGUSR1: user-defined signal 1",
|
||||
/* 31 */ Q+I+R, "SIGUSR2: user-defined signal 2",
|
||||
/* 32 */ Q+I+R, "SIGTHR: reserved",
|
||||
};
|
||||
#undef C
|
||||
#undef I
|
||||
|
@ -48,8 +48,9 @@ sighandler(int32 sig, Siginfo* info, void* context)
|
||||
Sigcontext *sc;
|
||||
|
||||
if(sigtab[sig].flags & SigQueue) {
|
||||
sigsend(sig);
|
||||
return;
|
||||
if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
|
||||
return;
|
||||
exit(2); // SIGINT, SIGTERM, etc
|
||||
}
|
||||
|
||||
if(panicking) // traceback already printed
|
||||
|
@ -57,8 +57,9 @@ sighandler(int32 sig, Siginfo* info, void* context)
|
||||
Sigcontext *sc;
|
||||
|
||||
if(sigtab[sig].flags & SigQueue) {
|
||||
sigsend(sig);
|
||||
return;
|
||||
if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
|
||||
return;
|
||||
exit(2); // SIGINT, SIGTERM, etc
|
||||
}
|
||||
|
||||
if(panicking) // traceback already printed
|
||||
|
@ -18,27 +18,27 @@ static SigTab sigtab[] = {
|
||||
/* 7 */ C, "SIGBUS: bus error",
|
||||
/* 8 */ C, "SIGFPE: floating-point exception",
|
||||
/* 9 */ 0, "SIGKILL: kill",
|
||||
/* 10 */ Q+R, "SIGUSR1: user-defined signal 1",
|
||||
/* 10 */ Q+I+R, "SIGUSR1: user-defined signal 1",
|
||||
/* 11 */ C, "SIGSEGV: segmentation violation",
|
||||
/* 12 */ Q+R, "SIGUSR2: user-defined signal 2",
|
||||
/* 12 */ Q+I+R, "SIGUSR2: user-defined signal 2",
|
||||
/* 13 */ I, "SIGPIPE: write to broken pipe",
|
||||
/* 14 */ Q+R, "SIGALRM: alarm clock",
|
||||
/* 14 */ Q+I+R, "SIGALRM: alarm clock",
|
||||
/* 15 */ Q+R, "SIGTERM: termination",
|
||||
/* 16 */ Q+R, "SIGSTKFLT: stack fault",
|
||||
/* 17 */ Q+R, "SIGCHLD: child status has changed",
|
||||
/* 16 */ C, "SIGSTKFLT: stack fault",
|
||||
/* 17 */ I+R, "SIGCHLD: child status has changed",
|
||||
/* 18 */ 0, "SIGCONT: continue",
|
||||
/* 19 */ 0, "SIGSTOP: stop, unblockable",
|
||||
/* 20 */ Q+R, "SIGTSTP: keyboard stop",
|
||||
/* 21 */ Q+R, "SIGTTIN: background read from tty",
|
||||
/* 22 */ Q+R, "SIGTTOU: background write to tty",
|
||||
/* 23 */ Q+R, "SIGURG: urgent condition on socket",
|
||||
/* 24 */ Q+R, "SIGXCPU: cpu limit exceeded",
|
||||
/* 25 */ Q+R, "SIGXFSZ: file size limit exceeded",
|
||||
/* 26 */ Q+R, "SIGVTALRM: virtual alarm clock",
|
||||
/* 27 */ Q+R, "SIGPROF: profiling alarm clock",
|
||||
/* 28 */ Q+R, "SIGWINCH: window size change",
|
||||
/* 29 */ Q+R, "SIGIO: i/o now possible",
|
||||
/* 30 */ Q+R, "SIGPWR: power failure restart",
|
||||
/* 20 */ Q+I+R, "SIGTSTP: keyboard stop",
|
||||
/* 21 */ Q+I+R, "SIGTTIN: background read from tty",
|
||||
/* 22 */ Q+I+R, "SIGTTOU: background write to tty",
|
||||
/* 23 */ Q+I+R, "SIGURG: urgent condition on socket",
|
||||
/* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
|
||||
/* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
|
||||
/* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
|
||||
/* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
|
||||
/* 28 */ Q+I+R, "SIGWINCH: window size change",
|
||||
/* 29 */ Q+I+R, "SIGIO: i/o now possible",
|
||||
/* 30 */ Q+I+R, "SIGPWR: power failure restart",
|
||||
/* 31 */ C, "SIGSYS: bad system call",
|
||||
};
|
||||
#undef C
|
||||
|
@ -374,10 +374,10 @@ void breakpoint(void);
|
||||
void gosched(void);
|
||||
void goexit(void);
|
||||
void runcgo(void (*fn)(void*), void*);
|
||||
void entersyscall(void);
|
||||
void exitsyscall(void);
|
||||
void runtime·entersyscall(void);
|
||||
void runtime·exitsyscall(void);
|
||||
void siginit(void);
|
||||
void sigsend(int32 sig);
|
||||
bool sigsend(int32 sig);
|
||||
|
||||
#pragma varargck argpos printf 1
|
||||
|
||||
|
@ -43,6 +43,7 @@ package runtime
|
||||
static struct {
|
||||
Note;
|
||||
uint32 mask;
|
||||
bool inuse;
|
||||
} sig;
|
||||
|
||||
void
|
||||
@ -52,24 +53,27 @@ siginit(void)
|
||||
}
|
||||
|
||||
// Called from sighandler to send a signal back out of the signal handling thread.
|
||||
void
|
||||
bool
|
||||
sigsend(int32 s)
|
||||
{
|
||||
uint32 bit, mask;
|
||||
|
||||
if(!sig.inuse)
|
||||
return false;
|
||||
bit = 1 << s;
|
||||
for(;;) {
|
||||
mask = sig.mask;
|
||||
if(mask & bit)
|
||||
return; // signal already in queue
|
||||
break; // signal already in queue
|
||||
if(cas(&sig.mask, mask, mask|bit)) {
|
||||
// Added to queue.
|
||||
// Only send a wakeup for the first signal in each round.
|
||||
if(mask == 0)
|
||||
notewakeup(&sig);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called to receive a bitmask of queued signals.
|
||||
@ -88,3 +92,7 @@ func Sigrecv() (m uint32) {
|
||||
func Signame(sig int32) (name String) {
|
||||
name = signame(sig);
|
||||
}
|
||||
|
||||
func Siginit() {
|
||||
sig.inuse = true; // enable reception of signals; cannot disable
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user