mirror of
https://github.com/golang/go
synced 2024-11-23 03:40:02 -07:00
runtime: forward crashing signals to late handlers
CL 49590 made it possible for external signal handlers to catch signals from a crashing Go process. This CL extends that support to handlers registered after the Go runtime has initialized. Updates #20392 (and possibly fix it). Change-Id: I18eccd5e958a505f4d1782a7fc51c16bd3a4ff9c Reviewed-on: https://go-review.googlesource.com/57291 Run-TryBot: Elias Naur <elias.naur@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
176cd48e57
commit
c3189cee71
@ -430,12 +430,16 @@ func TestCatchPanic(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, early := range []bool{true, false} {
|
||||
cmd := testEnv(exec.Command(exe, "CgoCatchPanic"))
|
||||
// Make sure a panic results in a crash.
|
||||
cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
|
||||
if early {
|
||||
// Tell testprogcgo to install an early signal handler for SIGABRT
|
||||
cmd.Env = append(cmd.Env, "CGOCATCHPANIC_INSTALL_HANDLER=1")
|
||||
cmd.Env = append(cmd.Env, "CGOCATCHPANIC_EARLY_HANDLER=1")
|
||||
}
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Errorf("testprogcgo CgoCatchPanic failed: %v\n%s", err, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -604,6 +604,7 @@ const (
|
||||
_SigGoExit // cause all runtime procs to exit (only used on Plan 9).
|
||||
_SigSetStack // add SA_ONSTACK to libc handler
|
||||
_SigUnblock // unblocked in minit
|
||||
_SigIgn // _SIG_DFL action is to ignore the signal
|
||||
)
|
||||
|
||||
// Layout of in-memory per-function information prepared by linker
|
||||
|
@ -21,20 +21,20 @@ var sigtable = [...]sigTabT{
|
||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
||||
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||
/* 17 */ {0, "SIGSTOP: stop"},
|
||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify + _SigUnblock, "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"},
|
||||
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||
/* 23 */ {_SigNotify + _SigIgn, "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 + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
||||
/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
|
||||
/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||
/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
|
||||
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||
}
|
||||
|
@ -21,20 +21,20 @@ var sigtable = [...]sigTabT{
|
||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
||||
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||
/* 17 */ {0, "SIGSTOP: stop"},
|
||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify + _SigUnblock, "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"},
|
||||
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||
/* 23 */ {_SigNotify + _SigIgn, "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 + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
||||
/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
|
||||
/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||
/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
|
||||
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||
/* 32 */ {_SigNotify, "SIGTHR: reserved"},
|
||||
|
@ -21,20 +21,20 @@ var sigtable = [...]sigTabT{
|
||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
||||
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||
/* 17 */ {0, "SIGSTOP: stop"},
|
||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify + _SigUnblock, "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"},
|
||||
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||
/* 23 */ {_SigNotify + _SigIgn, "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 + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
||||
/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
|
||||
/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||
/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
|
||||
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||
/* 32 */ {_SigNotify, "SIGTHR: reserved"},
|
||||
|
@ -26,13 +26,13 @@ var sigtable = [...]sigTabT{
|
||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
||||
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||
/* 17 */ {0, "SIGSTOP: stop"},
|
||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault, "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"},
|
||||
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify + _SigIgn, "SIGCHLD: child status has changed"},
|
||||
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "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"},
|
||||
|
@ -21,20 +21,20 @@ var sigtable = [...]sigTabT{
|
||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
||||
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||
/* 17 */ {0, "SIGSTOP: stop"},
|
||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify + _SigUnblock, "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"},
|
||||
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||
/* 23 */ {_SigNotify + _SigIgn, "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 + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
||||
/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
|
||||
/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||
/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
|
||||
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||
/* 32 */ {_SigNotify, "SIGTHR: reserved"},
|
||||
|
@ -21,13 +21,13 @@ var sigtable = [...]sigTabT{
|
||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
||||
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||
/* 17 */ {0, "SIGSTOP: stop"},
|
||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
|
||||
/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
||||
/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
||||
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||
/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "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"},
|
||||
|
@ -23,16 +23,16 @@ var sigtable = [...]sigTabT{
|
||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: software termination signal from kill"},
|
||||
/* 16 */ {_SigNotify, "SIGUSR1: user defined signal 1"},
|
||||
/* 17 */ {_SigNotify, "SIGUSR2: user defined signal 2"},
|
||||
/* 18 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status change alias (POSIX)"},
|
||||
/* 18 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status change alias (POSIX)"},
|
||||
/* 19 */ {_SigNotify, "SIGPWR: power-fail restart"},
|
||||
/* 20 */ {_SigNotify, "SIGWINCH: window size change"},
|
||||
/* 21 */ {_SigNotify, "SIGURG: urgent socket condition"},
|
||||
/* 20 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||
/* 21 */ {_SigNotify + _SigIgn, "SIGURG: urgent socket condition"},
|
||||
/* 22 */ {_SigNotify, "SIGPOLL: pollable event occurred"},
|
||||
/* 23 */ {0, "SIGSTOP: stop (cannot be caught or ignored)"},
|
||||
/* 24 */ {_SigNotify + _SigDefault, "SIGTSTP: user stop requested from tty"},
|
||||
/* 25 */ {_SigNotify + _SigDefault, "SIGCONT: stopped process has been continued"},
|
||||
/* 26 */ {_SigNotify + _SigDefault, "SIGTTIN: background tty read attempted"},
|
||||
/* 27 */ {_SigNotify + _SigDefault, "SIGTTOU: background tty write attempted"},
|
||||
/* 24 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: user stop requested from tty"},
|
||||
/* 25 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: stopped process has been continued"},
|
||||
/* 26 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background tty read attempted"},
|
||||
/* 27 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background tty write attempted"},
|
||||
/* 28 */ {_SigNotify, "SIGVTALRM: virtual timer expired"},
|
||||
/* 29 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling timer expired"},
|
||||
/* 30 */ {_SigNotify, "SIGXCPU: exceeded cpu limit"},
|
||||
|
@ -405,13 +405,8 @@ func sigpanic() {
|
||||
//go:nowritebarrierrec
|
||||
func dieFromSignal(sig uint32) {
|
||||
unblocksig(sig)
|
||||
// First, try any signal handler installed before the runtime
|
||||
// initialized.
|
||||
fn := atomic.Loaduintptr(&fwdSig[sig])
|
||||
// On Darwin, sigtramp is called even for non-Go signal handlers.
|
||||
// Mark the signal as unhandled to ensure it is forwarded.
|
||||
atomic.Store(&handlingSig[sig], 0)
|
||||
setsig(sig, fn)
|
||||
raise(sig)
|
||||
|
||||
// That should have killed us. On some systems, though, raise
|
||||
@ -601,17 +596,23 @@ func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
|
||||
return false
|
||||
}
|
||||
fwdFn := atomic.Loaduintptr(&fwdSig[sig])
|
||||
flags := sigtable[sig].flags
|
||||
|
||||
if !signalsOK {
|
||||
// The only way we can get here is if we are in a
|
||||
// library or archive, we installed a signal handler
|
||||
// at program startup, but the Go runtime has not yet
|
||||
// been initialized.
|
||||
if fwdFn == _SIG_DFL {
|
||||
dieFromSignal(sig)
|
||||
} else {
|
||||
sigfwd(fwdFn, sig, info, ctx)
|
||||
// If we aren't handling the signal, forward it.
|
||||
if atomic.Load(&handlingSig[sig]) == 0 || !signalsOK {
|
||||
// If the signal is ignored, doing nothing is the same as forwarding.
|
||||
if fwdFn == _SIG_IGN || (fwdFn == _SIG_DFL && flags&_SigIgn != 0) {
|
||||
return true
|
||||
}
|
||||
// We are not handling the signal and there is no other handler to forward to.
|
||||
// Crash with the default behavior.
|
||||
if fwdFn == _SIG_DFL {
|
||||
setsig(sig, _SIG_DFL)
|
||||
dieFromSignal(sig)
|
||||
return false
|
||||
}
|
||||
|
||||
sigfwd(fwdFn, sig, info, ctx)
|
||||
return true
|
||||
}
|
||||
|
||||
@ -620,18 +621,6 @@ func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// If we aren't handling the signal, forward it.
|
||||
// Really if we aren't handling the signal, we shouldn't get here,
|
||||
// but on Darwin setsigstack can lead us here because it sets
|
||||
// the sa_tramp field. The sa_tramp field is not returned by
|
||||
// sigaction, so the fix for that is non-obvious.
|
||||
if atomic.Load(&handlingSig[sig]) == 0 {
|
||||
sigfwd(fwdFn, sig, info, ctx)
|
||||
return true
|
||||
}
|
||||
|
||||
flags := sigtable[sig].flags
|
||||
|
||||
c := &sigctxt{info, ctx}
|
||||
// Only forward synchronous signals and SIGPIPE.
|
||||
// Unfortunately, user generated SIGPIPEs will also be forwarded, because si_code
|
||||
|
@ -28,18 +28,18 @@ var sigtable = [...]sigTabT{
|
||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||
/* 16 */ {_SigThrow + _SigUnblock, "SIGSTKFLT: stack fault"},
|
||||
/* 17 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
|
||||
/* 18 */ {_SigNotify + _SigDefault, "SIGCONT: continue"},
|
||||
/* 17 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "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"},
|
||||
/* 20 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||
/* 23 */ {_SigNotify + _SigIgn, "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 + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
||||
/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||
/* 29 */ {_SigNotify, "SIGIO: i/o now possible"},
|
||||
/* 30 */ {_SigNotify, "SIGPWR: power failure restart"},
|
||||
/* 31 */ {_SigThrow, "SIGSYS: bad system call"},
|
||||
|
@ -26,16 +26,16 @@ var sigtable = [...]sigTabT{
|
||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||
/* 16 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||
/* 17 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||
/* 18 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
|
||||
/* 18 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||
/* 19 */ {_SigNotify, "SIGPWR: power failure restart"},
|
||||
/* 20 */ {_SigNotify, "SIGWINCH: window size change"},
|
||||
/* 21 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
||||
/* 20 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||
/* 21 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||
/* 22 */ {_SigNotify, "SIGIO: i/o now possible"},
|
||||
/* 23 */ {0, "SIGSTOP: stop, unblockable"},
|
||||
/* 24 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
||||
/* 25 */ {_SigNotify + _SigDefault, "SIGCONT: continue"},
|
||||
/* 26 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
||||
/* 27 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
||||
/* 24 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||
/* 25 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue"},
|
||||
/* 26 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||
/* 27 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||
/* 28 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
||||
/* 29 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||
/* 30 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
||||
|
15
src/runtime/testdata/testprogcgo/catchpanic.go
vendored
15
src/runtime/testdata/testprogcgo/catchpanic.go
vendored
@ -17,17 +17,21 @@ static void abrthandler(int signum) {
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__ ((constructor)) sigsetup(void) {
|
||||
void registerAbortHandler() {
|
||||
struct sigaction act;
|
||||
|
||||
if (getenv("CGOCATCHPANIC_INSTALL_HANDLER") == NULL)
|
||||
return;
|
||||
memset(&act, 0, sizeof act);
|
||||
act.sa_handler = abrthandler;
|
||||
sigaction(SIGABRT, &act, NULL);
|
||||
}
|
||||
|
||||
static void __attribute__ ((constructor)) sigsetup(void) {
|
||||
if (getenv("CGOCATCHPANIC_EARLY_HANDLER") == NULL)
|
||||
return;
|
||||
registerAbortHandler();
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import "os"
|
||||
|
||||
func init() {
|
||||
register("CgoCatchPanic", CgoCatchPanic)
|
||||
@ -35,5 +39,8 @@ func init() {
|
||||
|
||||
// Test that the SIGABRT raised by panic can be caught by an early signal handler.
|
||||
func CgoCatchPanic() {
|
||||
if _, ok := os.LookupEnv("CGOCATCHPANIC_EARLY_HANDLER"); !ok {
|
||||
C.registerAbortHandler()
|
||||
}
|
||||
panic("catch me")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user