aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/signal_unix.go
diff options
context:
space:
mode:
authorElias Naur <elias.naur@gmail.com>2017-08-19 16:59:19 +0200
committerElias Naur <elias.naur@gmail.com>2017-08-29 07:40:19 +0000
commitc3189cee717a47dd7936d9f82904db72b28293f6 (patch)
treee3fc16aff861b031fec26f74f79ed10ce085ff5a /src/runtime/signal_unix.go
parent176cd48e574817bbb912c139396324c187b31279 (diff)
downloadgo-c3189cee717a47dd7936d9f82904db72b28293f6.tar.gz
go-c3189cee717a47dd7936d9f82904db72b28293f6.zip
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>
Diffstat (limited to 'src/runtime/signal_unix.go')
-rw-r--r--src/runtime/signal_unix.go37
1 files changed, 13 insertions, 24 deletions
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index 973e5f924f..5ea4b9f631 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 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)
- } else {
- sigfwd(fwdFn, sig, info, ctx)
+ 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