mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: allow signal.Ignore of user-generated throwing signals
Today, signal.Ignore(syscall.SIGTRAP) does nothing while signal.Notify(make(chan os.Signal), syscall.SIGTRAP) correctly discards user-generated SIGTRAPs. The same applies to any signal that we throw on. Make signal.Ignore work for these signals. Fixes #12906. Change-Id: Iba244813051e0ce23fa32fbad3e3fa596a941094 Reviewed-on: https://go-review.googlesource.com/18348 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
331a6055ab
commit
81adfa508a
9 changed files with 72 additions and 6 deletions
|
|
@ -151,3 +151,11 @@ func TestSignalExitStatus(t *testing.T) {
|
||||||
t.Errorf("got %v; expected SIGTERM", ee)
|
t.Errorf("got %v; expected SIGTERM", ee)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSignalIgnoreSIGTRAP(t *testing.T) {
|
||||||
|
output := runTestProg(t, "testprognet", "SignalIgnoreSIGTRAP")
|
||||||
|
want := "OK\n"
|
||||||
|
if output != want {
|
||||||
|
t.Fatalf("want %s, got %s\n", want, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,10 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.sigcode() == _SI_USER && signal_ignored(sig) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if flags&_SigKill != 0 {
|
if flags&_SigKill != 0 {
|
||||||
dieFromSignal(int32(sig))
|
dieFromSignal(int32(sig))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,10 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.sigcode() == _SI_USER && signal_ignored(sig) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if flags&_SigKill != 0 {
|
if flags&_SigKill != 0 {
|
||||||
dieFromSignal(int32(sig))
|
dieFromSignal(int32(sig))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,10 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.sigcode() == _SI_USER && signal_ignored(sig) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if flags&_SigKill != 0 {
|
if flags&_SigKill != 0 {
|
||||||
dieFromSignal(int32(sig))
|
dieFromSignal(int32(sig))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,10 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.sigcode() == _SI_USER && signal_ignored(sig) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if flags&_SigKill != 0 {
|
if flags&_SigKill != 0 {
|
||||||
dieFromSignal(int32(sig))
|
dieFromSignal(int32(sig))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,10 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.sigcode() == _SI_USER && signal_ignored(sig) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if flags&_SigKill != 0 {
|
if flags&_SigKill != 0 {
|
||||||
dieFromSignal(int32(sig))
|
dieFromSignal(int32(sig))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,10 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.sigcode() == _SI_USER && signal_ignored(sig) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if flags&_SigKill != 0 {
|
if flags&_SigKill != 0 {
|
||||||
dieFromSignal(int32(sig))
|
dieFromSignal(int32(sig))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var sig struct {
|
var sig struct {
|
||||||
note note
|
note note
|
||||||
mask [(_NSIG + 31) / 32]uint32
|
mask [(_NSIG + 31) / 32]uint32
|
||||||
wanted [(_NSIG + 31) / 32]uint32
|
wanted [(_NSIG + 31) / 32]uint32
|
||||||
recv [(_NSIG + 31) / 32]uint32
|
ignored [(_NSIG + 31) / 32]uint32
|
||||||
state uint32
|
recv [(_NSIG + 31) / 32]uint32
|
||||||
inuse bool
|
state uint32
|
||||||
|
inuse bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -146,6 +147,7 @@ func signal_enable(s uint32) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sig.wanted[s/32] |= 1 << (s & 31)
|
sig.wanted[s/32] |= 1 << (s & 31)
|
||||||
|
sig.ignored[s/32] &^= 1 << (s & 31)
|
||||||
sigenable(s)
|
sigenable(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,9 +168,15 @@ func signal_ignore(s uint32) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sig.wanted[s/32] &^= 1 << (s & 31)
|
sig.wanted[s/32] &^= 1 << (s & 31)
|
||||||
|
sig.ignored[s/32] |= 1 << (s & 31)
|
||||||
sigignore(s)
|
sigignore(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checked by signal handlers.
|
||||||
|
func signal_ignored(s uint32) bool {
|
||||||
|
return sig.ignored[s/32]&(1<<(s&31)) != 0
|
||||||
|
}
|
||||||
|
|
||||||
// This runs on a foreign stack, without an m or a g. No stack split.
|
// This runs on a foreign stack, without an m or a g. No stack split.
|
||||||
//go:nosplit
|
//go:nosplit
|
||||||
//go:norace
|
//go:norace
|
||||||
|
|
|
||||||
26
src/runtime/testdata/testprognet/signal.go
vendored
Normal file
26
src/runtime/testdata/testprognet/signal.go
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !windows,!plan9,!nacl
|
||||||
|
|
||||||
|
// This is in testprognet instead of testprog because testprog
|
||||||
|
// must not import anything (like net, but also like os/signal)
|
||||||
|
// that kicks off background goroutines during init.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
register("SignalIgnoreSIGTRAP", SignalIgnoreSIGTRAP)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SignalIgnoreSIGTRAP() {
|
||||||
|
signal.Ignore(syscall.SIGTRAP)
|
||||||
|
syscall.Kill(syscall.Getpid(), syscall.SIGTRAP)
|
||||||
|
println("OK")
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue