]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: allow signal.Ignore of user-generated throwing signals
authorRuss Cox <rsc@golang.org>
Thu, 7 Jan 2016 15:19:55 +0000 (10:19 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 8 Jan 2016 15:34:03 +0000 (15:34 +0000)
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>

src/runtime/crash_unix_test.go
src/runtime/signal_386.go
src/runtime/signal_amd64x.go
src/runtime/signal_arm.go
src/runtime/signal_arm64.go
src/runtime/signal_mips64x.go
src/runtime/signal_ppc64x.go
src/runtime/sigqueue.go
src/runtime/testdata/testprognet/signal.go [new file with mode: 0644]

index 59425271c5820448271dddf5bf5c4666e6bcf477..a7af7eff285efe40b401bd3f15672940a26c3546 100644 (file)
@@ -151,3 +151,11 @@ func TestSignalExitStatus(t *testing.T) {
                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)
+       }
+}
index 5c53582f908e673f6e76c27fd75f76a3051526b7..0374f4a2d7825ef7b5f0ae17042191562057ec3e 100644 (file)
@@ -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 {
                dieFromSignal(int32(sig))
        }
index 834e85563c7757a1e0025bfc76eefae689966f37..0f6700dbf1a66d7ef4d82d57739427fa4866a5cd 100644 (file)
@@ -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 {
                dieFromSignal(int32(sig))
        }
index 9ea48dff8a615b68d69969d9bec96d44dc48a191..3ea3938e59790271bd0f186d8e4c34b44d630445 100644 (file)
@@ -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 {
                dieFromSignal(int32(sig))
        }
index 9a83bf0c97f06c5e72cfe4bb1a795d57257041ca..e647c7685014aee424f96ce354fbc729201fb8c7 100644 (file)
@@ -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 {
                dieFromSignal(int32(sig))
        }
index 868e993104ae160a78a11a1e5c2822a71b2f3443..77c27148e86fac1e6e7a76c364ce19d12c77949e 100644 (file)
@@ -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 {
                dieFromSignal(int32(sig))
        }
index ee263484aa4affc24e9dbfa273b6f5c603f8bb5a..1c868b84a123b14578c50bd5de83d42af950dbb1 100644 (file)
@@ -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 {
                dieFromSignal(int32(sig))
        }
index 8c9951ae1d220c57b1d24c6ff93bc8897ff2c1dd..84616ebceba780beec8eb00c8e3b2b815f2cbcb5 100644 (file)
@@ -34,12 +34,13 @@ import (
 )
 
 var sig struct {
-       note   note
-       mask   [(_NSIG + 31) / 32]uint32
-       wanted [(_NSIG + 31) / 32]uint32
-       recv   [(_NSIG + 31) / 32]uint32
-       state  uint32
-       inuse  bool
+       note    note
+       mask    [(_NSIG + 31) / 32]uint32
+       wanted  [(_NSIG + 31) / 32]uint32
+       ignored [(_NSIG + 31) / 32]uint32
+       recv    [(_NSIG + 31) / 32]uint32
+       state   uint32
+       inuse   bool
 }
 
 const (
@@ -146,6 +147,7 @@ func signal_enable(s uint32) {
                return
        }
        sig.wanted[s/32] |= 1 << (s & 31)
+       sig.ignored[s/32] &^= 1 << (s & 31)
        sigenable(s)
 }
 
@@ -166,9 +168,15 @@ func signal_ignore(s uint32) {
                return
        }
        sig.wanted[s/32] &^= 1 << (s & 31)
+       sig.ignored[s/32] |= 1 << (s & 31)
        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.
 //go:nosplit
 //go:norace
diff --git a/src/runtime/testdata/testprognet/signal.go b/src/runtime/testdata/testprognet/signal.go
new file mode 100644 (file)
index 0000000..24d1424
--- /dev/null
@@ -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")
+}