From c3189cee717a47dd7936d9f82904db72b28293f6 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 19 Aug 2017 16:59:19 +0200 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/runtime/crash_cgo_test.go | 18 ++++---- src/runtime/runtime2.go | 1 + src/runtime/signal_darwin.go | 18 ++++---- src/runtime/signal_dragonfly.go | 18 ++++---- src/runtime/signal_freebsd.go | 18 ++++---- src/runtime/signal_nacl.go | 12 +++--- src/runtime/signal_netbsd.go | 18 ++++---- src/runtime/signal_openbsd.go | 12 +++--- src/runtime/signal_solaris.go | 14 +++---- src/runtime/signal_unix.go | 41 +++++++------------ src/runtime/sigtab_linux_generic.go | 14 +++---- src/runtime/sigtab_linux_mipsx.go | 14 +++---- .../testdata/testprogcgo/catchpanic.go | 15 +++++-- 13 files changed, 107 insertions(+), 106 deletions(-) diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go index 2869ac76872..40d12dc3dd9 100644 --- a/src/runtime/crash_cgo_test.go +++ b/src/runtime/crash_cgo_test.go @@ -430,12 +430,16 @@ func TestCatchPanic(t *testing.T) { t.Fatal(err) } - cmd := testEnv(exec.Command(exe, "CgoCatchPanic")) - // Make sure a panic results in a crash. - cmd.Env = append(cmd.Env, "GOTRACEBACK=crash") - // Tell testprogcgo to install an early signal handler for SIGABRT - cmd.Env = append(cmd.Env, "CGOCATCHPANIC_INSTALL_HANDLER=1") - if out, err := cmd.CombinedOutput(); err != nil { - t.Errorf("testprogcgo CgoCatchPanic failed: %v\n%s", err, out) + 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_EARLY_HANDLER=1") + } + if out, err := cmd.CombinedOutput(); err != nil { + t.Errorf("testprogcgo CgoCatchPanic failed: %v\n%s", err, out) + } } } diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go index 366dfc9f456..b439a319760 100644 --- a/src/runtime/runtime2.go +++ b/src/runtime/runtime2.go @@ -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 diff --git a/src/runtime/signal_darwin.go b/src/runtime/signal_darwin.go index 581b4d04fb9..8090fb22a5c 100644 --- a/src/runtime/signal_darwin.go +++ b/src/runtime/signal_darwin.go @@ -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"}, } diff --git a/src/runtime/signal_dragonfly.go b/src/runtime/signal_dragonfly.go index aae46e75d02..f2b26e71791 100644 --- a/src/runtime/signal_dragonfly.go +++ b/src/runtime/signal_dragonfly.go @@ -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"}, diff --git a/src/runtime/signal_freebsd.go b/src/runtime/signal_freebsd.go index 0bbbd2a809d..2812c69989f 100644 --- a/src/runtime/signal_freebsd.go +++ b/src/runtime/signal_freebsd.go @@ -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"}, diff --git a/src/runtime/signal_nacl.go b/src/runtime/signal_nacl.go index 47930757da8..ad321d8b759 100644 --- a/src/runtime/signal_nacl.go +++ b/src/runtime/signal_nacl.go @@ -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"}, diff --git a/src/runtime/signal_netbsd.go b/src/runtime/signal_netbsd.go index 32a9bb0b83c..ca510842e19 100644 --- a/src/runtime/signal_netbsd.go +++ b/src/runtime/signal_netbsd.go @@ -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"}, diff --git a/src/runtime/signal_openbsd.go b/src/runtime/signal_openbsd.go index 32a9bb0b83c..99c601ce58a 100644 --- a/src/runtime/signal_openbsd.go +++ b/src/runtime/signal_openbsd.go @@ -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"}, diff --git a/src/runtime/signal_solaris.go b/src/runtime/signal_solaris.go index dc1db764061..a8eeeee129e 100644 --- a/src/runtime/signal_solaris.go +++ b/src/runtime/signal_solaris.go @@ -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"}, diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go index 973e5f924f1..5ea4b9f6315 100644 --- a/src/runtime/signal_unix.go +++ b/src/runtime/signal_unix.go @@ -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 diff --git a/src/runtime/sigtab_linux_generic.go b/src/runtime/sigtab_linux_generic.go index 9a8e58f4913..b26040b8031 100644 --- a/src/runtime/sigtab_linux_generic.go +++ b/src/runtime/sigtab_linux_generic.go @@ -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"}, diff --git a/src/runtime/sigtab_linux_mipsx.go b/src/runtime/sigtab_linux_mipsx.go index 9f6e259cdb3..81dd2314c56 100644 --- a/src/runtime/sigtab_linux_mipsx.go +++ b/src/runtime/sigtab_linux_mipsx.go @@ -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"}, diff --git a/src/runtime/testdata/testprogcgo/catchpanic.go b/src/runtime/testdata/testprogcgo/catchpanic.go index f03b6d3ea36..55a606d1bc8 100644 --- a/src/runtime/testdata/testprogcgo/catchpanic.go +++ b/src/runtime/testdata/testprogcgo/catchpanic.go @@ -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") }