Skip to content

Commit 41cf01f

Browse files
committed
pkg/signal.CatchAll: ignore SIGURG on Linux
Do not handle SIGURG on Linux, as in go1.14+, the go runtime issues SIGURG as an interrupt to support preemptable system calls on Linux. This issue was caught in TestCatchAll, which could fail when updating to Go 1.14 or above; === Failed === FAIL: pkg/signal TestCatchAll (0.01s) signal_linux_test.go:32: assertion failed: urgent I/O condition (string) != continued (string) signal_linux_test.go:32: assertion failed: continued (string) != hangup (string) signal_linux_test.go:32: assertion failed: hangup (string) != child exited (string) signal_linux_test.go:32: assertion failed: child exited (string) != illegal instruction (string) signal_linux_test.go:32: assertion failed: illegal instruction (string) != floating point exception (string) Signed-off-by: Sebastiaan van Stijn <github@gone.nl> (cherry picked from commit b7ebf32) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent a23a880 commit 41cf01f

File tree

7 files changed

+49
-0
lines changed

7 files changed

+49
-0
lines changed

pkg/signal/signal.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,16 @@ import (
1212
)
1313

1414
// CatchAll catches all signals and relays them to the specified channel.
15+
// On Linux, SIGURG is not handled, as it's used by the Go runtime to support
16+
// preemptable system calls.
1517
func CatchAll(sigc chan os.Signal) {
1618
var handledSigs []os.Signal
1719
for _, s := range SignalMap {
20+
if isRuntimeSig(s) {
21+
// Do not handle SIGURG on Linux, as in go1.14+, the go runtime issues
22+
// SIGURG as an interrupt to support preemptable system calls on Linux.
23+
continue
24+
}
1825
handledSigs = append(handledSigs, s)
1926
}
2027
signal.Notify(sigc, handledSigs...)

pkg/signal/signal_darwin.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package signal // import "github.com/docker/docker/pkg/signal"
22

33
import (
4+
"os"
45
"syscall"
56
)
67

@@ -39,3 +40,7 @@ var SignalMap = map[string]syscall.Signal{
3940
"XCPU": syscall.SIGXCPU,
4041
"XFSZ": syscall.SIGXFSZ,
4142
}
43+
44+
func isRuntimeSig(_ os.Signal) bool {
45+
return false
46+
}

pkg/signal/signal_freebsd.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package signal // import "github.com/docker/docker/pkg/signal"
22

33
import (
4+
"os"
45
"syscall"
56
)
67

@@ -41,3 +42,7 @@ var SignalMap = map[string]syscall.Signal{
4142
"XCPU": syscall.SIGXCPU,
4243
"XFSZ": syscall.SIGXFSZ,
4344
}
45+
46+
func isRuntimeSig(_ os.Signal) bool {
47+
return false
48+
}

pkg/signal/signal_linux.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package signal // import "github.com/docker/docker/pkg/signal"
44

55
import (
6+
"os"
67
"syscall"
78

89
"golang.org/x/sys/unix"
@@ -81,3 +82,7 @@ var SignalMap = map[string]syscall.Signal{
8182
"RTMAX-1": sigrtmax - 1,
8283
"RTMAX": sigrtmax,
8384
}
85+
86+
func isRuntimeSig(s os.Signal) bool {
87+
return s == unix.SIGURG
88+
}

pkg/signal/signal_linux_mipsx.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package signal // import "github.com/docker/docker/pkg/signal"
55

66
import (
7+
"os"
78
"syscall"
89

910
"golang.org/x/sys/unix"
@@ -82,3 +83,7 @@ var SignalMap = map[string]syscall.Signal{
8283
"RTMAX-1": sigrtmax - 1,
8384
"RTMAX": sigrtmax,
8485
}
86+
87+
func isRuntimeSig(s os.Signal) bool {
88+
return s == unix.SIGURG
89+
}

pkg/signal/signal_linux_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"os"
77
"syscall"
88
"testing"
9+
"time"
910

1011
"gotest.tools/v3/assert"
1112
is "gotest.tools/v3/assert/cmp"
@@ -34,6 +35,22 @@ func TestCatchAll(t *testing.T) {
3435
}
3536
}
3637

38+
func TestCatchAllIgnoreSigUrg(t *testing.T) {
39+
sigs := make(chan os.Signal, 1)
40+
CatchAll(sigs)
41+
defer StopCatch(sigs)
42+
43+
err := syscall.Kill(syscall.Getpid(), syscall.SIGURG)
44+
assert.NilError(t, err)
45+
timer := time.NewTimer(1 * time.Second)
46+
defer timer.Stop()
47+
select {
48+
case <-timer.C:
49+
case s := <-sigs:
50+
t.Fatalf("expected no signals to be handled, but received %q", s.String())
51+
}
52+
}
53+
3754
func TestStopCatch(t *testing.T) {
3855
signal := SignalMap["HUP"]
3956
channel := make(chan os.Signal, 1)

pkg/signal/signal_windows.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package signal // import "github.com/docker/docker/pkg/signal"
22

33
import (
4+
"os"
45
"syscall"
56
)
67

@@ -24,3 +25,7 @@ var SignalMap = map[string]syscall.Signal{
2425
"KILL": syscall.SIGKILL,
2526
"TERM": syscall.SIGTERM,
2627
}
28+
29+
func isRuntimeSig(_ os.Signal) bool {
30+
return false
31+
}

0 commit comments

Comments
 (0)