Commit 08579c26 authored by Russ Cox's avatar Russ Cox

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
parent 96ee38bf
...@@ -41,6 +41,7 @@ func process(ch chan<- Signal) { ...@@ -41,6 +41,7 @@ func process(ch chan<- Signal) {
} }
func init() { func init() {
runtime.Siginit()
ch := make(chan Signal) // Done here so Incoming can have type <-chan Signal ch := make(chan Signal) // Done here so Incoming can have type <-chan Signal
Incoming = ch Incoming = ch
go process(ch) go process(ch)
......
...@@ -41,8 +41,9 @@ sighandler(int32 sig, Siginfo *info, void *context) ...@@ -41,8 +41,9 @@ sighandler(int32 sig, Siginfo *info, void *context)
Regs *r; Regs *r;
if(sigtab[sig].flags & SigQueue) { if(sigtab[sig].flags & SigQueue) {
sigsend(sig); if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
return; return;
exit(2); // SIGINT, SIGTERM, etc
} }
if(panicking) // traceback already printed if(panicking) // traceback already printed
......
...@@ -49,8 +49,9 @@ sighandler(int32 sig, Siginfo *info, void *context) ...@@ -49,8 +49,9 @@ sighandler(int32 sig, Siginfo *info, void *context)
Regs *r; Regs *r;
if(sigtab[sig].flags & SigQueue) { if(sigtab[sig].flags & SigQueue) {
sigsend(sig); if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
return; return;
exit(2); // SIGINT, SIGTERM, etc
} }
if(panicking) // traceback already printed if(panicking) // traceback already printed
......
...@@ -22,24 +22,24 @@ static SigTab sigtab[] = { ...@@ -22,24 +22,24 @@ static SigTab sigtab[] = {
/* 11 */ C, "SIGSEGV: segmentation violation", /* 11 */ C, "SIGSEGV: segmentation violation",
/* 12 */ C, "SIGSYS: bad system call", /* 12 */ C, "SIGSYS: bad system call",
/* 13 */ I, "SIGPIPE: write to broken pipe", /* 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", /* 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", /* 17 */ 0, "SIGSTOP: stop",
/* 18 */ Q+R, "SIGTSTP: keyboard stop", /* 18 */ Q+I+R, "SIGTSTP: keyboard stop",
/* 19 */ 0, "SIGCONT: continue after stop", /* 19 */ 0, "SIGCONT: continue after stop",
/* 20 */ I+R, "SIGCHLD: child status has changed", /* 20 */ I+R, "SIGCHLD: child status has changed",
/* 21 */ Q+R, "SIGTTIN: background read from tty", /* 21 */ Q+I+R, "SIGTTIN: background read from tty",
/* 22 */ Q+R, "SIGTTOU: background write to tty", /* 22 */ Q+I+R, "SIGTTOU: background write to tty",
/* 23 */ Q+R, "SIGIO: i/o now possible", /* 23 */ Q+I+R, "SIGIO: i/o now possible",
/* 24 */ Q+R, "SIGXCPU: cpu limit exceeded", /* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
/* 25 */ Q+R, "SIGXFSZ: file size limit exceeded", /* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
/* 26 */ Q+R, "SIGVTALRM: virtual alarm clock", /* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
/* 27 */ Q+R, "SIGPROF: profiling alarm clock", /* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
/* 28 */ Q+R, "SIGWINCH: window size change", /* 28 */ Q+I+R, "SIGWINCH: window size change",
/* 29 */ Q+R, "SIGINFO: status request from keyboard", /* 29 */ Q+I+R, "SIGINFO: status request from keyboard",
/* 30 */ Q+R, "SIGUSR1: user-defined signal 1", /* 30 */ Q+I+R, "SIGUSR1: user-defined signal 1",
/* 31 */ Q+R, "SIGUSR2: user-defined signal 2", /* 31 */ Q+I+R, "SIGUSR2: user-defined signal 2",
}; };
#undef C #undef C
#undef I #undef I
......
...@@ -66,3 +66,7 @@ func Sigrecv() uint32 ...@@ -66,3 +66,7 @@ func Sigrecv() uint32
// Signame returns a string describing the signal, or "" if the signal is unknown. // Signame returns a string describing the signal, or "" if the signal is unknown.
func Signame(sig int32) string 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) ...@@ -51,8 +51,9 @@ sighandler(int32 sig, Siginfo* info, void* context)
Mcontext *mc; Mcontext *mc;
if(sigtab[sig].flags & SigQueue) { if(sigtab[sig].flags & SigQueue) {
sigsend(sig); if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
return; return;
exit(2); // SIGINT, SIGTERM, etc
} }
if(panicking) // traceback already printed if(panicking) // traceback already printed
......
...@@ -59,8 +59,9 @@ sighandler(int32 sig, Siginfo* info, void* context) ...@@ -59,8 +59,9 @@ sighandler(int32 sig, Siginfo* info, void* context)
Mcontext *mc; Mcontext *mc;
if(sigtab[sig].flags & SigQueue) { if(sigtab[sig].flags & SigQueue) {
sigsend(sig); if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
return; return;
exit(2); // SIGINT, SIGTERM, etc
} }
if(panicking) // traceback already printed if(panicking) // traceback already printed
......
...@@ -22,25 +22,25 @@ static SigTab sigtab[] = { ...@@ -22,25 +22,25 @@ static SigTab sigtab[] = {
/* 11 */ C, "SIGSEGV: segmentation violation", /* 11 */ C, "SIGSEGV: segmentation violation",
/* 12 */ C, "SIGSYS: bad system call", /* 12 */ C, "SIGSYS: bad system call",
/* 13 */ I, "SIGPIPE: write to broken pipe", /* 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", /* 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", /* 17 */ 0, "SIGSTOP: stop, unblockable",
/* 18 */ Q+R, "SIGTSTP: stop from tty", /* 18 */ Q+I+R, "SIGTSTP: stop from tty",
/* 19 */ 0, "SIGCONT: continue", /* 19 */ 0, "SIGCONT: continue",
/* 20 */ I+R, "SIGCHLD: child status has changed", /* 20 */ I+R, "SIGCHLD: child status has changed",
/* 21 */ Q+R, "SIGTTIN: background read from tty", /* 21 */ Q+I+R, "SIGTTIN: background read from tty",
/* 22 */ Q+R, "SIGTTOU: background write to tty", /* 22 */ Q+I+R, "SIGTTOU: background write to tty",
/* 23 */ Q+R, "SIGIO: i/o now possible", /* 23 */ Q+I+R, "SIGIO: i/o now possible",
/* 24 */ Q+R, "SIGXCPU: cpu limit exceeded", /* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
/* 25 */ Q+R, "SIGXFSZ: file size limit exceeded", /* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
/* 26 */ Q+R, "SIGVTALRM: virtual alarm clock", /* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
/* 27 */ Q+R, "SIGPROF: profiling alarm clock", /* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
/* 28 */ I+R, "SIGWINCH: window size change", /* 28 */ Q+I+R, "SIGWINCH: window size change",
/* 29 */ Q+R, "SIGINFO: information request", /* 29 */ Q+I+R, "SIGINFO: information request",
/* 30 */ Q+R, "SIGUSR1: user-defined signal 1", /* 30 */ Q+I+R, "SIGUSR1: user-defined signal 1",
/* 31 */ Q+R, "SIGUSR2: user-defined signal 2", /* 31 */ Q+I+R, "SIGUSR2: user-defined signal 2",
/* 32 */ Q+R, "SIGTHR: reserved", /* 32 */ Q+I+R, "SIGTHR: reserved",
}; };
#undef C #undef C
#undef I #undef I
......
...@@ -48,8 +48,9 @@ sighandler(int32 sig, Siginfo* info, void* context) ...@@ -48,8 +48,9 @@ sighandler(int32 sig, Siginfo* info, void* context)
Sigcontext *sc; Sigcontext *sc;
if(sigtab[sig].flags & SigQueue) { if(sigtab[sig].flags & SigQueue) {
sigsend(sig); if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
return; return;
exit(2); // SIGINT, SIGTERM, etc
} }
if(panicking) // traceback already printed if(panicking) // traceback already printed
......
...@@ -57,8 +57,9 @@ sighandler(int32 sig, Siginfo* info, void* context) ...@@ -57,8 +57,9 @@ sighandler(int32 sig, Siginfo* info, void* context)
Sigcontext *sc; Sigcontext *sc;
if(sigtab[sig].flags & SigQueue) { if(sigtab[sig].flags & SigQueue) {
sigsend(sig); if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
return; return;
exit(2); // SIGINT, SIGTERM, etc
} }
if(panicking) // traceback already printed if(panicking) // traceback already printed
......
...@@ -18,27 +18,27 @@ static SigTab sigtab[] = { ...@@ -18,27 +18,27 @@ static SigTab sigtab[] = {
/* 7 */ C, "SIGBUS: bus error", /* 7 */ C, "SIGBUS: bus error",
/* 8 */ C, "SIGFPE: floating-point exception", /* 8 */ C, "SIGFPE: floating-point exception",
/* 9 */ 0, "SIGKILL: kill", /* 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", /* 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", /* 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", /* 15 */ Q+R, "SIGTERM: termination",
/* 16 */ Q+R, "SIGSTKFLT: stack fault", /* 16 */ C, "SIGSTKFLT: stack fault",
/* 17 */ Q+R, "SIGCHLD: child status has changed", /* 17 */ I+R, "SIGCHLD: child status has changed",
/* 18 */ 0, "SIGCONT: continue", /* 18 */ 0, "SIGCONT: continue",
/* 19 */ 0, "SIGSTOP: stop, unblockable", /* 19 */ 0, "SIGSTOP: stop, unblockable",
/* 20 */ Q+R, "SIGTSTP: keyboard stop", /* 20 */ Q+I+R, "SIGTSTP: keyboard stop",
/* 21 */ Q+R, "SIGTTIN: background read from tty", /* 21 */ Q+I+R, "SIGTTIN: background read from tty",
/* 22 */ Q+R, "SIGTTOU: background write to tty", /* 22 */ Q+I+R, "SIGTTOU: background write to tty",
/* 23 */ Q+R, "SIGURG: urgent condition on socket", /* 23 */ Q+I+R, "SIGURG: urgent condition on socket",
/* 24 */ Q+R, "SIGXCPU: cpu limit exceeded", /* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
/* 25 */ Q+R, "SIGXFSZ: file size limit exceeded", /* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
/* 26 */ Q+R, "SIGVTALRM: virtual alarm clock", /* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
/* 27 */ Q+R, "SIGPROF: profiling alarm clock", /* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
/* 28 */ Q+R, "SIGWINCH: window size change", /* 28 */ Q+I+R, "SIGWINCH: window size change",
/* 29 */ Q+R, "SIGIO: i/o now possible", /* 29 */ Q+I+R, "SIGIO: i/o now possible",
/* 30 */ Q+R, "SIGPWR: power failure restart", /* 30 */ Q+I+R, "SIGPWR: power failure restart",
/* 31 */ C, "SIGSYS: bad system call", /* 31 */ C, "SIGSYS: bad system call",
}; };
#undef C #undef C
......
...@@ -374,10 +374,10 @@ void breakpoint(void); ...@@ -374,10 +374,10 @@ void breakpoint(void);
void gosched(void); void gosched(void);
void goexit(void); void goexit(void);
void runcgo(void (*fn)(void*), void*); void runcgo(void (*fn)(void*), void*);
void entersyscall(void); void runtime·entersyscall(void);
void exitsyscall(void); void runtime·exitsyscall(void);
void siginit(void); void siginit(void);
void sigsend(int32 sig); bool sigsend(int32 sig);
#pragma varargck argpos printf 1 #pragma varargck argpos printf 1
......
...@@ -43,6 +43,7 @@ package runtime ...@@ -43,6 +43,7 @@ package runtime
static struct { static struct {
Note; Note;
uint32 mask; uint32 mask;
bool inuse;
} sig; } sig;
void void
...@@ -52,24 +53,27 @@ siginit(void) ...@@ -52,24 +53,27 @@ siginit(void)
} }
// Called from sighandler to send a signal back out of the signal handling thread. // Called from sighandler to send a signal back out of the signal handling thread.
void bool
sigsend(int32 s) sigsend(int32 s)
{ {
uint32 bit, mask; uint32 bit, mask;
if(!sig.inuse)
return false;
bit = 1 << s; bit = 1 << s;
for(;;) { for(;;) {
mask = sig.mask; mask = sig.mask;
if(mask & bit) if(mask & bit)
return; // signal already in queue break; // signal already in queue
if(cas(&sig.mask, mask, mask|bit)) { if(cas(&sig.mask, mask, mask|bit)) {
// Added to queue. // Added to queue.
// Only send a wakeup for the first signal in each round. // Only send a wakeup for the first signal in each round.
if(mask == 0) if(mask == 0)
notewakeup(&sig); notewakeup(&sig);
return; break;
} }
} }
return true;
} }
// Called to receive a bitmask of queued signals. // Called to receive a bitmask of queued signals.
...@@ -88,3 +92,7 @@ func Sigrecv() (m uint32) { ...@@ -88,3 +92,7 @@ func Sigrecv() (m uint32) {
func Signame(sig int32) (name String) { func Signame(sig int32) (name String) {
name = signame(sig); name = signame(sig);
} }
func Siginit() {
sig.inuse = true; // enable reception of signals; cannot disable
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment