// Send SIGQUIT to get a stack trace.
var sigquit = syscall.SIGQUIT
+func init() {
+ if runtime.Sigisblocked(int(syscall.SIGQUIT)) {
+ // We can't use SIGQUIT to kill subprocesses because
+ // it's blocked. Use SIGKILL instead. See issue
+ // #19196 for an example of when this happens.
+ sigquit = syscall.SIGKILL
+ }
+}
+
func TestCrashDumpsAllThreads(t *testing.T) {
switch runtime.GOOS {
case "darwin", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
t.Skipf("skipping; not supported on %v", runtime.GOOS)
}
+ if runtime.Sigisblocked(int(syscall.SIGQUIT)) {
+ t.Skip("skipping; SIGQUIT is blocked, see golang.org/issue/19196")
+ }
+
// We don't use executeTest because we need to kill the
// program while it is running.
t.Skip("Skipping in short mode (GOTRACEBACK=crash is slow)")
}
+ if runtime.Sigisblocked(int(syscall.SIGQUIT)) {
+ t.Skip("skipping; SIGQUIT is blocked, see golang.org/issue/19196")
+ }
+
t.Parallel()
cmd := exec.Command(os.Args[0], "testPanicSystemstackInternal")
cmd = testEnv(cmd)
--- /dev/null
+// Copyright 2017 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 darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package runtime
+
+func sigismember(mask *sigset, i int) bool {
+ clear := *mask
+ sigdelset(&clear, i)
+ return clear != *mask
+}
+
+func Sigisblocked(i int) bool {
+ var sigmask sigset
+ sigprocmask(_SIG_SETMASK, nil, &sigmask)
+ return sigismember(&sigmask, i)
+}