mirror of
https://github.com/golang/go
synced 2024-11-19 12:04:43 -07:00
runtime: forward crashing signals to late handlers
CL 49590 made it possible for external signal handlers to catch signals from a crashing Go process. This CL extends that support to handlers registered after the Go runtime has initialized. Updates #20392 (and possibly fix it). Change-Id: I18eccd5e958a505f4d1782a7fc51c16bd3a4ff9c Reviewed-on: https://go-review.googlesource.com/57291 Run-TryBot: Elias Naur <elias.naur@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
176cd48e57
commit
c3189cee71
@ -430,12 +430,16 @@ func TestCatchPanic(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, early := range []bool{true, false} {
|
||||||
cmd := testEnv(exec.Command(exe, "CgoCatchPanic"))
|
cmd := testEnv(exec.Command(exe, "CgoCatchPanic"))
|
||||||
// Make sure a panic results in a crash.
|
// Make sure a panic results in a crash.
|
||||||
cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
|
cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
|
||||||
|
if early {
|
||||||
// Tell testprogcgo to install an early signal handler for SIGABRT
|
// Tell testprogcgo to install an early signal handler for SIGABRT
|
||||||
cmd.Env = append(cmd.Env, "CGOCATCHPANIC_INSTALL_HANDLER=1")
|
cmd.Env = append(cmd.Env, "CGOCATCHPANIC_EARLY_HANDLER=1")
|
||||||
|
}
|
||||||
if out, err := cmd.CombinedOutput(); err != nil {
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
t.Errorf("testprogcgo CgoCatchPanic failed: %v\n%s", err, out)
|
t.Errorf("testprogcgo CgoCatchPanic failed: %v\n%s", err, out)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -604,6 +604,7 @@ const (
|
|||||||
_SigGoExit // cause all runtime procs to exit (only used on Plan 9).
|
_SigGoExit // cause all runtime procs to exit (only used on Plan 9).
|
||||||
_SigSetStack // add SA_ONSTACK to libc handler
|
_SigSetStack // add SA_ONSTACK to libc handler
|
||||||
_SigUnblock // unblocked in minit
|
_SigUnblock // unblocked in minit
|
||||||
|
_SigIgn // _SIG_DFL action is to ignore the signal
|
||||||
)
|
)
|
||||||
|
|
||||||
// Layout of in-memory per-function information prepared by linker
|
// Layout of in-memory per-function information prepared by linker
|
||||||
|
@ -21,20 +21,20 @@ var sigtable = [...]sigTabT{
|
|||||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||||
/* 17 */ {0, "SIGSTOP: stop"},
|
/* 17 */ {0, "SIGSTOP: stop"},
|
||||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||||
/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
|
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||||
/* 20 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
|
/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||||
/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||||
/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||||
/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
|
/* 23 */ {_SigNotify + _SigIgn, "SIGIO: i/o now possible"},
|
||||||
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
||||||
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
||||||
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
||||||
/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||||
/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
|
/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
|
||||||
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||||
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||||
}
|
}
|
||||||
|
@ -21,20 +21,20 @@ var sigtable = [...]sigTabT{
|
|||||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||||
/* 17 */ {0, "SIGSTOP: stop"},
|
/* 17 */ {0, "SIGSTOP: stop"},
|
||||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||||
/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
|
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||||
/* 20 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
|
/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||||
/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||||
/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||||
/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
|
/* 23 */ {_SigNotify + _SigIgn, "SIGIO: i/o now possible"},
|
||||||
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
||||||
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
||||||
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
||||||
/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||||
/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
|
/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
|
||||||
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||||
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||||
/* 32 */ {_SigNotify, "SIGTHR: reserved"},
|
/* 32 */ {_SigNotify, "SIGTHR: reserved"},
|
||||||
|
@ -21,20 +21,20 @@ var sigtable = [...]sigTabT{
|
|||||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||||
/* 17 */ {0, "SIGSTOP: stop"},
|
/* 17 */ {0, "SIGSTOP: stop"},
|
||||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||||
/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
|
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||||
/* 20 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
|
/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||||
/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||||
/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||||
/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
|
/* 23 */ {_SigNotify + _SigIgn, "SIGIO: i/o now possible"},
|
||||||
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
||||||
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
||||||
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
||||||
/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||||
/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
|
/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
|
||||||
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||||
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||||
/* 32 */ {_SigNotify, "SIGTHR: reserved"},
|
/* 32 */ {_SigNotify, "SIGTHR: reserved"},
|
||||||
|
@ -26,13 +26,13 @@ var sigtable = [...]sigTabT{
|
|||||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||||
/* 17 */ {0, "SIGSTOP: stop"},
|
/* 17 */ {0, "SIGSTOP: stop"},
|
||||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||||
/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
|
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||||
/* 20 */ {_SigNotify, "SIGCHLD: child status has changed"},
|
/* 20 */ {_SigNotify + _SigIgn, "SIGCHLD: child status has changed"},
|
||||||
/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||||
/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||||
/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
|
/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
|
||||||
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
||||||
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
||||||
|
@ -21,20 +21,20 @@ var sigtable = [...]sigTabT{
|
|||||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||||
/* 17 */ {0, "SIGSTOP: stop"},
|
/* 17 */ {0, "SIGSTOP: stop"},
|
||||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||||
/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
|
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||||
/* 20 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
|
/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||||
/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||||
/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||||
/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
|
/* 23 */ {_SigNotify + _SigIgn, "SIGIO: i/o now possible"},
|
||||||
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
||||||
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
||||||
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
||||||
/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||||
/* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
|
/* 29 */ {_SigNotify + _SigIgn, "SIGINFO: status request from keyboard"},
|
||||||
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
/* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||||
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||||
/* 32 */ {_SigNotify, "SIGTHR: reserved"},
|
/* 32 */ {_SigNotify, "SIGTHR: reserved"},
|
||||||
|
@ -21,13 +21,13 @@ var sigtable = [...]sigTabT{
|
|||||||
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
/* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
|
||||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||||
/* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
/* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||||
/* 17 */ {0, "SIGSTOP: stop"},
|
/* 17 */ {0, "SIGSTOP: stop"},
|
||||||
/* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||||
/* 19 */ {_SigNotify + _SigDefault, "SIGCONT: continue after stop"},
|
/* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue after stop"},
|
||||||
/* 20 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
|
/* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||||
/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||||
/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||||
/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
|
/* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
|
||||||
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
||||||
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
||||||
|
@ -23,16 +23,16 @@ var sigtable = [...]sigTabT{
|
|||||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: software termination signal from kill"},
|
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: software termination signal from kill"},
|
||||||
/* 16 */ {_SigNotify, "SIGUSR1: user defined signal 1"},
|
/* 16 */ {_SigNotify, "SIGUSR1: user defined signal 1"},
|
||||||
/* 17 */ {_SigNotify, "SIGUSR2: user defined signal 2"},
|
/* 17 */ {_SigNotify, "SIGUSR2: user defined signal 2"},
|
||||||
/* 18 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status change alias (POSIX)"},
|
/* 18 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status change alias (POSIX)"},
|
||||||
/* 19 */ {_SigNotify, "SIGPWR: power-fail restart"},
|
/* 19 */ {_SigNotify, "SIGPWR: power-fail restart"},
|
||||||
/* 20 */ {_SigNotify, "SIGWINCH: window size change"},
|
/* 20 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||||
/* 21 */ {_SigNotify, "SIGURG: urgent socket condition"},
|
/* 21 */ {_SigNotify + _SigIgn, "SIGURG: urgent socket condition"},
|
||||||
/* 22 */ {_SigNotify, "SIGPOLL: pollable event occurred"},
|
/* 22 */ {_SigNotify, "SIGPOLL: pollable event occurred"},
|
||||||
/* 23 */ {0, "SIGSTOP: stop (cannot be caught or ignored)"},
|
/* 23 */ {0, "SIGSTOP: stop (cannot be caught or ignored)"},
|
||||||
/* 24 */ {_SigNotify + _SigDefault, "SIGTSTP: user stop requested from tty"},
|
/* 24 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: user stop requested from tty"},
|
||||||
/* 25 */ {_SigNotify + _SigDefault, "SIGCONT: stopped process has been continued"},
|
/* 25 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: stopped process has been continued"},
|
||||||
/* 26 */ {_SigNotify + _SigDefault, "SIGTTIN: background tty read attempted"},
|
/* 26 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background tty read attempted"},
|
||||||
/* 27 */ {_SigNotify + _SigDefault, "SIGTTOU: background tty write attempted"},
|
/* 27 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background tty write attempted"},
|
||||||
/* 28 */ {_SigNotify, "SIGVTALRM: virtual timer expired"},
|
/* 28 */ {_SigNotify, "SIGVTALRM: virtual timer expired"},
|
||||||
/* 29 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling timer expired"},
|
/* 29 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling timer expired"},
|
||||||
/* 30 */ {_SigNotify, "SIGXCPU: exceeded cpu limit"},
|
/* 30 */ {_SigNotify, "SIGXCPU: exceeded cpu limit"},
|
||||||
|
@ -405,13 +405,8 @@ func sigpanic() {
|
|||||||
//go:nowritebarrierrec
|
//go:nowritebarrierrec
|
||||||
func dieFromSignal(sig uint32) {
|
func dieFromSignal(sig uint32) {
|
||||||
unblocksig(sig)
|
unblocksig(sig)
|
||||||
// First, try any signal handler installed before the runtime
|
|
||||||
// initialized.
|
|
||||||
fn := atomic.Loaduintptr(&fwdSig[sig])
|
|
||||||
// On Darwin, sigtramp is called even for non-Go signal handlers.
|
|
||||||
// Mark the signal as unhandled to ensure it is forwarded.
|
// Mark the signal as unhandled to ensure it is forwarded.
|
||||||
atomic.Store(&handlingSig[sig], 0)
|
atomic.Store(&handlingSig[sig], 0)
|
||||||
setsig(sig, fn)
|
|
||||||
raise(sig)
|
raise(sig)
|
||||||
|
|
||||||
// That should have killed us. On some systems, though, raise
|
// That should have killed us. On some systems, though, raise
|
||||||
@ -601,17 +596,23 @@ func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
fwdFn := atomic.Loaduintptr(&fwdSig[sig])
|
fwdFn := atomic.Loaduintptr(&fwdSig[sig])
|
||||||
|
flags := sigtable[sig].flags
|
||||||
|
|
||||||
if !signalsOK {
|
// If we aren't handling the signal, forward it.
|
||||||
// The only way we can get here is if we are in a
|
if atomic.Load(&handlingSig[sig]) == 0 || !signalsOK {
|
||||||
// library or archive, we installed a signal handler
|
// If the signal is ignored, doing nothing is the same as forwarding.
|
||||||
// at program startup, but the Go runtime has not yet
|
if fwdFn == _SIG_IGN || (fwdFn == _SIG_DFL && flags&_SigIgn != 0) {
|
||||||
// been initialized.
|
return true
|
||||||
if fwdFn == _SIG_DFL {
|
|
||||||
dieFromSignal(sig)
|
|
||||||
} else {
|
|
||||||
sigfwd(fwdFn, sig, info, ctx)
|
|
||||||
}
|
}
|
||||||
|
// We are not handling the signal and there is no other handler to forward to.
|
||||||
|
// Crash with the default behavior.
|
||||||
|
if fwdFn == _SIG_DFL {
|
||||||
|
setsig(sig, _SIG_DFL)
|
||||||
|
dieFromSignal(sig)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
sigfwd(fwdFn, sig, info, ctx)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,18 +621,6 @@ func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we aren't handling the signal, forward it.
|
|
||||||
// Really if we aren't handling the signal, we shouldn't get here,
|
|
||||||
// but on Darwin setsigstack can lead us here because it sets
|
|
||||||
// the sa_tramp field. The sa_tramp field is not returned by
|
|
||||||
// sigaction, so the fix for that is non-obvious.
|
|
||||||
if atomic.Load(&handlingSig[sig]) == 0 {
|
|
||||||
sigfwd(fwdFn, sig, info, ctx)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
flags := sigtable[sig].flags
|
|
||||||
|
|
||||||
c := &sigctxt{info, ctx}
|
c := &sigctxt{info, ctx}
|
||||||
// Only forward synchronous signals and SIGPIPE.
|
// Only forward synchronous signals and SIGPIPE.
|
||||||
// Unfortunately, user generated SIGPIPEs will also be forwarded, because si_code
|
// Unfortunately, user generated SIGPIPEs will also be forwarded, because si_code
|
||||||
|
@ -28,18 +28,18 @@ var sigtable = [...]sigTabT{
|
|||||||
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
/* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
|
||||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||||
/* 16 */ {_SigThrow + _SigUnblock, "SIGSTKFLT: stack fault"},
|
/* 16 */ {_SigThrow + _SigUnblock, "SIGSTKFLT: stack fault"},
|
||||||
/* 17 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
|
/* 17 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||||
/* 18 */ {_SigNotify + _SigDefault, "SIGCONT: continue"},
|
/* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue"},
|
||||||
/* 19 */ {0, "SIGSTOP: stop, unblockable"},
|
/* 19 */ {0, "SIGSTOP: stop, unblockable"},
|
||||||
/* 20 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
/* 20 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||||
/* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
/* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||||
/* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
/* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||||
/* 23 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
/* 23 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||||
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
/* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
||||||
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
/* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
|
||||||
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
/* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
||||||
/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
/* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||||
/* 28 */ {_SigNotify, "SIGWINCH: window size change"},
|
/* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||||
/* 29 */ {_SigNotify, "SIGIO: i/o now possible"},
|
/* 29 */ {_SigNotify, "SIGIO: i/o now possible"},
|
||||||
/* 30 */ {_SigNotify, "SIGPWR: power failure restart"},
|
/* 30 */ {_SigNotify, "SIGPWR: power failure restart"},
|
||||||
/* 31 */ {_SigThrow, "SIGSYS: bad system call"},
|
/* 31 */ {_SigThrow, "SIGSYS: bad system call"},
|
||||||
|
@ -26,16 +26,16 @@ var sigtable = [...]sigTabT{
|
|||||||
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
/* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
|
||||||
/* 16 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
/* 16 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
|
||||||
/* 17 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
/* 17 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||||
/* 18 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
|
/* 18 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"},
|
||||||
/* 19 */ {_SigNotify, "SIGPWR: power failure restart"},
|
/* 19 */ {_SigNotify, "SIGPWR: power failure restart"},
|
||||||
/* 20 */ {_SigNotify, "SIGWINCH: window size change"},
|
/* 20 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"},
|
||||||
/* 21 */ {_SigNotify, "SIGURG: urgent condition on socket"},
|
/* 21 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"},
|
||||||
/* 22 */ {_SigNotify, "SIGIO: i/o now possible"},
|
/* 22 */ {_SigNotify, "SIGIO: i/o now possible"},
|
||||||
/* 23 */ {0, "SIGSTOP: stop, unblockable"},
|
/* 23 */ {0, "SIGSTOP: stop, unblockable"},
|
||||||
/* 24 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
|
/* 24 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"},
|
||||||
/* 25 */ {_SigNotify + _SigDefault, "SIGCONT: continue"},
|
/* 25 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue"},
|
||||||
/* 26 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
|
/* 26 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"},
|
||||||
/* 27 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
|
/* 27 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"},
|
||||||
/* 28 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
/* 28 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
|
||||||
/* 29 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
/* 29 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
|
||||||
/* 30 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
/* 30 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
|
||||||
|
15
src/runtime/testdata/testprogcgo/catchpanic.go
vendored
15
src/runtime/testdata/testprogcgo/catchpanic.go
vendored
@ -17,17 +17,21 @@ static void abrthandler(int signum) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__ ((constructor)) sigsetup(void) {
|
void registerAbortHandler() {
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
|
|
||||||
if (getenv("CGOCATCHPANIC_INSTALL_HANDLER") == NULL)
|
|
||||||
return;
|
|
||||||
memset(&act, 0, sizeof act);
|
memset(&act, 0, sizeof act);
|
||||||
act.sa_handler = abrthandler;
|
act.sa_handler = abrthandler;
|
||||||
sigaction(SIGABRT, &act, NULL);
|
sigaction(SIGABRT, &act, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __attribute__ ((constructor)) sigsetup(void) {
|
||||||
|
if (getenv("CGOCATCHPANIC_EARLY_HANDLER") == NULL)
|
||||||
|
return;
|
||||||
|
registerAbortHandler();
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
import "os"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
register("CgoCatchPanic", CgoCatchPanic)
|
register("CgoCatchPanic", CgoCatchPanic)
|
||||||
@ -35,5 +39,8 @@ func init() {
|
|||||||
|
|
||||||
// Test that the SIGABRT raised by panic can be caught by an early signal handler.
|
// Test that the SIGABRT raised by panic can be caught by an early signal handler.
|
||||||
func CgoCatchPanic() {
|
func CgoCatchPanic() {
|
||||||
|
if _, ok := os.LookupEnv("CGOCATCHPANIC_EARLY_HANDLER"); !ok {
|
||||||
|
C.registerAbortHandler()
|
||||||
|
}
|
||||||
panic("catch me")
|
panic("catch me")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user