|
| 1 | +// Copyright 2015 The Go Authors. All rights reserved. |
| 2 | +// Use of this source code is governed by a BSD-style |
| 3 | +// license that can be found in the LICENSE file. |
| 4 | + |
| 5 | +/* |
| 6 | +Package signal implements access to incoming signals. |
| 7 | +
|
| 8 | +Signals are primarily used on Unix-like systems. For the use of this |
| 9 | +package on Windows and Plan 9, see below. |
| 10 | +
|
| 11 | +Types of signals |
| 12 | +
|
| 13 | +The signals SIGKILL and SIGSTOP may not be caught by a program, and |
| 14 | +therefore can not be affected by this package. |
| 15 | +
|
| 16 | +Synchronous signals are signals triggered by errors in program |
| 17 | +execution: SIGBUS, SIGFPE, and SIGSEGV. These are only considered |
| 18 | +synchronous when caused by program execution, not when sent using |
| 19 | +os.Process.Kill or the kill program or some similar mechanism. In |
| 20 | +general, except as discussed below, Go programs will convert a |
| 21 | +synchronous signal into a run-time panic. |
| 22 | +
|
| 23 | +The remaining signals are asynchronous signals. They are not |
| 24 | +triggered by program errors, but are instead sent from the kernel or |
| 25 | +from some other program. |
| 26 | +
|
| 27 | +Of the asynchronous signals, the SIGHUP signal is sent when a program |
| 28 | +loses its controlling terminal. The SIGINT signal is sent when the |
| 29 | +user at the controlling terminal presses the interrupt character, |
| 30 | +which by default is ^C (Control-C). The SIGQUIT signal is sent when |
| 31 | +the user at the controlling terminal presses the quit character, which |
| 32 | +by default is ^\ (Control-Backslash). In general you can cause a |
| 33 | +program to simply exit by pressing ^C, and you can cause it to exit |
| 34 | +with a stack dump by pressing ^\. |
| 35 | +
|
| 36 | +Default behavior of signals in Go programs |
| 37 | +
|
| 38 | +By default, a synchronous signal is converted into a run-time panic. A |
| 39 | +SIGHUP, SIGINT, or SIGTERM signal causes the program to exit. A |
| 40 | +SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, or SIGSYS signal |
| 41 | +causes the program to exit with a stack dump. A SIGTSTP, SIGTTIN, or |
| 42 | +SIGTTOU signal gets the system default behavior (these signals are |
| 43 | +used by the shell for job control). The SIGPROF signal is handled |
| 44 | +directly by the Go runtime to implement runtime.CPUProfile. Other |
| 45 | +signals are ignored. |
| 46 | +
|
| 47 | +If the Go program is started with either SIGHUP or SIGINT ignored, |
| 48 | +they will remain ignored. Go always registers a handler for the other |
| 49 | +signals. |
| 50 | +
|
| 51 | +If the Go program is started with a non-empty signal mask, that will |
| 52 | +generally be honored. However, some signals are explicitly unblocked: |
| 53 | +the synchronous signals, SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF, |
| 54 | +and, on GNU/Linux, signals 32 (SIGCANCEL) and 33 (SIGSETXID) |
| 55 | +(SIGCANCEL and SIGSETXID are used internally by glibc). |
| 56 | +
|
| 57 | +Changing the behavior of signals in Go programs |
| 58 | +
|
| 59 | +The functions in this package allow a program to change the way Go |
| 60 | +programs handle signals. |
| 61 | +
|
| 62 | +Notify disables the default behavior for a given set of asynchronous |
| 63 | +signals and instead delivers them over one or more registered |
| 64 | +channels. Specifically, it applies to the signals SIGHUP, SIGINT, |
| 65 | +SIGQUIT, SIGABRT, and SIGTERM. It also applies to the job control |
| 66 | +signals SIGTSTP, SIGTTIN, and SIGTTOU, in which case the system |
| 67 | +default behavior does not occur. It also applies to some signals that |
| 68 | +are otherwise ignored: SIGUSR1, SIGUSR2, SIGPIPE, SIGALRM, SIGCHLD, |
| 69 | +SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGWINCH, SIGIO, SIGPWR, SIGSYS, |
| 70 | +SIGINFO, SIGTHR, SIGWAITING, SIGLWP, SIGFREEZE, SIGTHAW, SIGLOST, |
| 71 | +SIGXRES, SIGJVM1, SIGJVM2, and any real time signals used on the |
| 72 | +system. Note that not all of these signals are available on all |
| 73 | +systems. |
| 74 | +
|
| 75 | +If the program was started with SIGHUP or SIGINT ignored, and Notify |
| 76 | +is called for either signal, a signal handler will be installed for |
| 77 | +that signal and it will no longer be ignored. If, later, Reset or |
| 78 | +Ignore is called for that signal, or Stop is called on all channels |
| 79 | +passed to Notify for that signal, the signal will once again be |
| 80 | +ignored. Reset will restore the system default behavior for the |
| 81 | +signal, while Ignore will cause the system to ignore the signal |
| 82 | +entirely. |
| 83 | +
|
| 84 | +If the program is started with a non-empty signal mask, some signals |
| 85 | +will be explicitly unblocked as described above. If Notify is called |
| 86 | +for a blocked signal, it will be unblocked. If, later, Reset is |
| 87 | +called for that signal, or Stop is called on all channels passed to |
| 88 | +Notify for that signal, the signal will once again be blocked. |
| 89 | +
|
| 90 | +Go programs that use cgo or SWIG |
| 91 | +
|
| 92 | +In a Go program that includes non-Go code, typically C/C++ code |
| 93 | +accessed using cgo or SWIG, Go's startup code normally runs first. It |
| 94 | +configures the signal handlers as expected by the Go runtime, before |
| 95 | +the non-Go startup code runs. If the non-Go startup code wishes to |
| 96 | +install its own signal handlers, it must take certain steps to keep Go |
| 97 | +working well. This section documents those steps and the overall |
| 98 | +effect changes to signal handler settings by the non-Go code can have |
| 99 | +on Go programs. In rare cases, the non-Go code may run before the Go |
| 100 | +code, in which case the next section also applies. |
| 101 | +
|
| 102 | +If the non-Go code called by the Go program does not change any signal |
| 103 | +handlers or masks, then the behavior is the same as for a pure Go |
| 104 | +program. |
| 105 | +
|
| 106 | +If the non-Go code installs any signal handlers, it must use the |
| 107 | +SA_ONSTACK flag with sigaction. Failing to do so is likely to cause |
| 108 | +the program to crash if the signal is received. Go programs routinely |
| 109 | +run with a limited stack, and therefore set up an alternate signal |
| 110 | +stack. Also, the Go standard library expects that any signal handlers |
| 111 | +will use the SA_RESTART flag. Failing to do so may cause some library |
| 112 | +calls to return "interrupted system call" errors. |
| 113 | +
|
| 114 | +If the non-Go code installs a signal handler for any of the |
| 115 | +synchronous signals (SIGBUS, SIGFPE, SIGSEGV), then it should record |
| 116 | +the existing Go signal handler. If those signals occur while |
| 117 | +executing Go code, it should invoke the Go signal handler (whether the |
| 118 | +signal occurs while executing Go code can be determined by looking at |
| 119 | +the PC passed to the signal handler). Otherwise some Go run-time |
| 120 | +panics will not occur as expected. |
| 121 | +
|
| 122 | +If the non-Go code installs a signal handler for any of the |
| 123 | +asynchronous signals, it may invoke the Go signal handler or not as it |
| 124 | +chooses. Naturally, if it does not invoke the Go signal handler, the |
| 125 | +Go behavior described above will not occur. This can be an issue with |
| 126 | +the SIGPROF signal in particular. |
| 127 | +
|
| 128 | +The non-Go code should not change the signal mask on any threads |
| 129 | +created by the Go runtime. If the non-Go code starts new threads of |
| 130 | +its own, it may set the signal mask as it pleases. |
| 131 | +
|
| 132 | +If the non-Go code starts a new thread, changes the signal mask, and |
| 133 | +then invokes a Go function in that thread, the Go runtime will |
| 134 | +automatically unblock certain signals: the synchronous signals, |
| 135 | +SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF, SIGCANCEL, and |
| 136 | +SIGSETXID. When the Go function returns, the non-Go signal mask will |
| 137 | +be restored. |
| 138 | +
|
| 139 | +If the Go signal handler is invoked on a non-Go thread not running Go |
| 140 | +code, the handler generally forwards the signal to the non-Go code, as |
| 141 | +follows. If the signal is SIGPROF, the Go handler does |
| 142 | +nothing. Otherwise, the Go handler removes itself, unblocks the |
| 143 | +signal, and raises it again, to invoke any non-Go handler or default |
| 144 | +system handler. If the program does not exit, the Go handler then |
| 145 | +reinstalls itself and continues execution of the program. |
| 146 | +
|
| 147 | +Non-Go programs that call Go code |
| 148 | +
|
| 149 | +When Go code is built with options like -buildmode=c-shared, it will |
| 150 | +be run as part of an existing non-Go program. The non-Go code may |
| 151 | +have already installed signal handlers when the Go code starts (that |
| 152 | +may also happen in unusual cases when using cgo or SWIG; in that case, |
| 153 | +the discussion here applies). |
| 154 | +
|
| 155 | +If the Go runtime sees an existing signal handler for the SIGCANCEL or |
| 156 | +SIGSETXID signals (which are used only on GNU/Linux), it will turn on |
| 157 | +the SA_ONSTACK flag and otherwise keep the signal handler. |
| 158 | +
|
| 159 | +For other signals listed above, the Go runtime will install a signal |
| 160 | +handler. It will save any existing signal handler. If a synchronous |
| 161 | +signal arrives while executing non-Go code, the Go runtime will invoke |
| 162 | +the existing signal handler instead of the Go signal handler. |
| 163 | +
|
| 164 | +If a signal is delivered to a non-Go thread, it will act as described |
| 165 | +above, except that if there is an existing non-Go signal handler, that |
| 166 | +handler will be installed before raising the signal. |
| 167 | +
|
| 168 | +Windows |
| 169 | +
|
| 170 | +On Windows a ^C (Control-C) or ^BREAK (Control-Break) normally cause |
| 171 | +the program to exit. If Notify is called for os.SIGINT, ^C or ^BREAK |
| 172 | +will cause os.SIGINT to be sent on the channel, and the program will |
| 173 | +not exit. If Reset is called, or Stop is called on all channels passed |
| 174 | +to Notify, then the default behavior will be restored. |
| 175 | +
|
| 176 | +Plan 9 |
| 177 | +
|
| 178 | +On Plan 9, signals have type syscall.Note, which is a string. Calling |
| 179 | +Notify with a syscall.Note will cause that value to be sent on the |
| 180 | +channel when that string is posted as a note. |
| 181 | +
|
| 182 | +*/ |
| 183 | +package signal |
0 commit comments