aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/signal_unix.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-10-11 10:34:26 -0700
committerIan Lance Taylor <iant@golang.org>2019-10-11 19:57:32 +0000
commitfd33b2c97491f566e85e2806cb5d08e711b35400 (patch)
treeb4ced81d499601d26965b2d2642a0792a150c086 /src/runtime/signal_unix.go
parent33fac9bad86d7f3bba8926d92c33e5a0cf28061f (diff)
downloadgo-fd33b2c97491f566e85e2806cb5d08e711b35400.tar.gz
go-fd33b2c97491f566e85e2806cb5d08e711b35400.zip
runtime: when disabling SIGPROF handler, ignore SIGPROF
If the runtime disables the SIGPROF handler, because this is Go code that is linked into a non-Go program, then don't go back to the default handling of SIGPROF; just start ignoring SIGPROF. Otherwise the program can get killed by a stray SIGPROF that is delivered, presumably to a different thread, after profiling is disabled. Fixes #19320 Change-Id: Ifebae477d726699c8c82c867604b73110c1cf262 Reviewed-on: https://go-review.googlesource.com/c/go/+/200740 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src/runtime/signal_unix.go')
-rw-r--r--src/runtime/signal_unix.go20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index a9a65d5164..3db6133af0 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -242,10 +242,26 @@ func setProcessCPUProfiler(hz int32) {
}
} else {
// If the Go signal handler should be disabled by default,
- // disable it if it is enabled.
+ // switch back to the signal handler that was installed
+ // when we enabled profiling. We don't try to handle the case
+ // of a program that changes the SIGPROF handler while Go
+ // profiling is enabled.
+ //
+ // If no signal handler was installed before, then start
+ // ignoring SIGPROF signals. We do this, rather than change
+ // to SIG_DFL, because there may be a pending SIGPROF
+ // signal that has not yet been delivered to some other thread.
+ // If we change to SIG_DFL here, the program will crash
+ // when that SIGPROF is delivered. We assume that programs
+ // that use profiling don't want to crash on a stray SIGPROF.
+ // See issue 19320.
if !sigInstallGoHandler(_SIGPROF) {
if atomic.Cas(&handlingSig[_SIGPROF], 1, 0) {
- setsig(_SIGPROF, atomic.Loaduintptr(&fwdSig[_SIGPROF]))
+ h := atomic.Loaduintptr(&fwdSig[_SIGPROF])
+ if h == _SIG_DFL {
+ h = _SIG_IGN
+ }
+ setsig(_SIGPROF, h)
}
}
}