1 // Copyright 2012 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.
5 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
10 "runtime/internal/sys"
14 // For gccgo's C code to call:
15 //go:linkname initsig runtime.initsig
16 //go:linkname crash runtime.crash
17 //go:linkname resetcpuprofiler runtime.resetcpuprofiler
18 //go:linkname sigtrampgo runtime.sigtrampgo
20 //go:linkname os_sigpipe os.sigpipe
25 func signame(sig
uint32) string {
26 if sig
>= uint32(len(sigtable
)) {
29 return sigtable
[sig
].name
37 // Stores the signal handlers registered before Go installed its own.
38 // These signal handlers will be invoked in cases where Go doesn't want to
39 // handle a particular signal (e.g., signal occurred on a non-Go thread).
40 // See sigfwdgo() for more information on when the signals are forwarded.
42 // Signal forwarding is currently available only on Darwin and Linux.
43 var fwdSig
[_NSIG
]uintptr
45 // channels for synchronizing signal mask updates with the signal mask
48 disableSigChan
chan uint32
49 enableSigChan
chan uint32
50 maskUpdatedChan
chan struct{}
54 // _NSIG is the number of signals on this operating system.
55 // sigtable should describe what to do for all the possible signals.
56 if len(sigtable
) != _NSIG
{
57 print("runtime: len(sigtable)=", len(sigtable
), " _NSIG=", _NSIG
, "\n")
58 throw("bad sigtable len")
64 // Initialize signals.
65 // Called by libpreinit so runtime may not be initialized.
67 //go:nowritebarrierrec
68 func initsig(preinit
bool) {
70 // preinit is only passed as true if isarchive should be true.
75 // It's now OK for signal handlers to run.
79 // For c-archive/c-shared this is called by libpreinit with
81 if (isarchive || islibrary
) && !preinit
{
85 for i
:= uint32(0); i
< _NSIG
; i
++ {
87 if t
.flags
== 0 || t
.flags
&_SigDefault
!= 0 {
92 if !sigInstallGoHandler(i
) {
93 // Even if we are not installing a signal handler,
94 // set SA_ONSTACK if necessary.
95 if fwdSig
[i
] != _SIG_DFL
&& fwdSig
[i
] != _SIG_IGN
{
101 t
.flags |
= _SigHandling
102 setsig(i
, getSigtramp())
107 //go:nowritebarrierrec
108 func sigInstallGoHandler(sig
uint32) bool {
109 // For some signals, we respect an inherited SIG_IGN handler
110 // rather than insist on installing our own default handler.
111 // Even these signals can be fetched using the os/signal package.
113 case _SIGHUP
, _SIGINT
:
114 if fwdSig
[sig
] == _SIG_IGN
{
120 if t
.flags
&_SigSetStack
!= 0 {
124 // When built using c-archive or c-shared, only install signal
125 // handlers for synchronous signals.
126 if (isarchive || islibrary
) && t
.flags
&_SigPanic
== 0 {
133 func sigenable(sig
uint32) {
134 if sig
>= uint32(len(sigtable
)) {
139 if t
.flags
&_SigNotify
!= 0 {
143 if t
.flags
&_SigHandling
== 0 {
144 t
.flags |
= _SigHandling
145 fwdSig
[sig
] = getsig(sig
)
146 setsig(sig
, getSigtramp())
151 func sigdisable(sig
uint32) {
152 if sig
>= uint32(len(sigtable
)) {
157 if t
.flags
&_SigNotify
!= 0 {
159 disableSigChan
<- sig
162 // If initsig does not install a signal handler for a
163 // signal, then to go back to the state before Notify
164 // we should remove the one we installed.
165 if !sigInstallGoHandler(sig
) {
166 t
.flags
&^= _SigHandling
167 setsig(sig
, fwdSig
[sig
])
172 func sigignore(sig
uint32) {
173 if sig
>= uint32(len(sigtable
)) {
178 if t
.flags
&_SigNotify
!= 0 {
179 t
.flags
&^= _SigHandling
180 setsig(sig
, _SIG_IGN
)
184 func resetcpuprofiler(hz
int32) {
187 setitimer(_ITIMER_PROF
, &it
, nil)
189 it
.it_interval
.tv_sec
= 0
190 it
.it_interval
.set_usec(1000000 / hz
)
191 it
.it_value
= it
.it_interval
192 setitimer(_ITIMER_PROF
, &it
, nil)
199 if sigsend(_SIGPIPE
) {
202 dieFromSignal(_SIGPIPE
)
205 // sigtrampgo is called from the signal handler function, sigtramp,
206 // written in assembly code.
207 // This is called by the signal handler, and the world may be stopped.
209 //go:nowritebarrierrec
210 func sigtrampgo(sig
uint32, info
*_siginfo_t
, ctx unsafe
.Pointer
) {
211 if sigfwdgo(sig
, info
, ctx
) {
216 c
:= sigctxt
{info
, ctx
}
218 _
, pc
:= getSiginfo(info
, ctx
)
222 badsignal(uintptr(sig
), &c
)
227 sighandler(sig
, info
, ctx
, g
)
231 // sigpanic turns a synchronous signal into a run-time panic.
232 // If the signal handler sees a synchronous panic, it arranges the
233 // stack to look like the function where the signal occurred called
234 // sigpanic, sets the signal's PC value to sigpanic, and returns from
235 // the signal handler. The effect is that the program will act as
236 // though the function that got the signal simply called sigpanic
241 throw("unexpected signal during runtime execution")
246 if g
.sigcode0
== _BUS_ADRERR
&& g
.sigcode1
< 0x1000 {
249 // Support runtime/debug.SetPanicOnFault.
253 print("unexpected fault address ", hex(g
.sigcode1
), "\n")
256 if (g
.sigcode0
== 0 || g
.sigcode0
== _SEGV_MAPERR || g
.sigcode0
== _SEGV_ACCERR
) && g
.sigcode1
< 0x1000 {
259 // Support runtime/debug.SetPanicOnFault.
263 print("unexpected fault address ", hex(g
.sigcode1
), "\n")
275 if g
.sig
>= uint32(len(sigtable
)) {
276 // can't happen: we looked up g.sig in sigtable to decide to call sigpanic
277 throw("unexpected signal value")
279 panic(errorString(sigtable
[g
.sig
].name
))
282 // dieFromSignal kills the program with a signal.
283 // This provides the expected exit status for the shell.
284 // This is only called with fatal signals expected to kill the process.
286 //go:nowritebarrierrec
287 func dieFromSignal(sig
uint32) {
288 setsig(sig
, _SIG_DFL
)
292 // That should have killed us. On some systems, though, raise
293 // sends the signal to the whole process rather than to just
294 // the current thread, which means that the signal may not yet
295 // have been delivered. Give other threads a chance to run and
296 // pick up the signal.
301 // If we are still somehow running, just exit with the wrong status.
305 // raisebadsignal is called when a signal is received on a non-Go
306 // thread, and the Go program does not want to handle it (that is, the
307 // program has not called os/signal.Notify for the signal).
308 func raisebadsignal(sig
uint32, c
*sigctxt
) {
310 // Ignore profiling signals that arrive on non-Go threads.
318 handler
= fwdSig
[sig
]
321 // Reset the signal handler and raise the signal.
322 // We are currently running inside a signal handler, so the
323 // signal is blocked. We need to unblock it before raising the
324 // signal, or the signal we raise will be ignored until we return
325 // from the signal handler. We know that the signal was unblocked
326 // before entering the handler, or else we would not have received
327 // it. That means that we don't have to worry about blocking it
332 // If we're linked into a non-Go program we want to try to
333 // avoid modifying the original context in which the signal
334 // was raised. If the handler is the default, we know it
335 // is non-recoverable, so we don't have to worry about
336 // re-installing sighandler. At this point we can just
337 // return and the signal will be re-raised and caught by
338 // the default handler with the correct context.
339 if (isarchive || islibrary
) && handler
== _SIG_DFL
&& c
.sigcode() != _SI_USER
{
345 // Give the signal a chance to be delivered.
346 // In almost all real cases the program is about to crash,
347 // so sleeping here is not a waste of time.
350 // If the signal didn't cause the program to exit, restore the
351 // Go signal handler and carry on.
353 // We may receive another instance of the signal before we
354 // restore the Go handler, but that is not so bad: we know
355 // that the Go program has been ignoring the signal.
356 setsig(sig
, getSigtramp())
360 if GOOS
== "darwin" {
361 // OS X core dumps are linear dumps of the mapped memory,
362 // from the first virtual byte to the last, with zeros in the gaps.
363 // Because of the way we arrange the address space on 64-bit systems,
364 // this means the OS X core file will be >128 GB and even on a zippy
365 // workstation can take OS X well over an hour to write (uninterruptible).
366 // Save users from making that mistake.
367 if sys
.PtrSize
== 8 {
372 dieFromSignal(_SIGABRT
)
375 // ensureSigM starts one global, sleeping thread to make sure at least one thread
376 // is available to catch signals enabled for os/signal.
378 if maskUpdatedChan
!= nil {
381 maskUpdatedChan
= make(chan struct{})
382 disableSigChan
= make(chan uint32)
383 enableSigChan
= make(chan uint32)
385 // Signal masks are per-thread, so make sure this goroutine stays on one
388 defer UnlockOSThread()
389 // The sigBlocked mask contains the signals not active for os/signal,
390 // initially all signals except the essential. When signal.Notify()/Stop is called,
391 // sigenable/sigdisable in turn notify this thread to update its signal
393 var sigBlocked sigset
394 sigfillset(&sigBlocked
)
395 for i
:= range sigtable
{
396 if sigtable
[i
].flags
&_SigUnblock
!= 0 {
397 sigdelset(&sigBlocked
, i
)
400 sigprocmask(_SIG_SETMASK
, &sigBlocked
, nil)
403 case sig
:= <-enableSigChan
:
405 sigdelset(&sigBlocked
, int(sig
))
407 case sig
:= <-disableSigChan
:
409 sigaddset(&sigBlocked
, int(sig
))
412 sigprocmask(_SIG_SETMASK
, &sigBlocked
, nil)
413 maskUpdatedChan
<- struct{}{}
418 // This is called when we receive a signal when there is no signal stack.
419 // This can only happen if non-Go code calls sigaltstack to disable the
421 func noSignalStack(sig
uint32) {
422 println("signal", sig
, "received on thread with no signal stack")
423 throw("non-Go code disabled sigaltstack")
426 // This is called if we receive a signal when there is a signal stack
427 // but we are not on it. This can only happen if non-Go code called
428 // sigaction without setting the SS_ONSTACK flag.
429 func sigNotOnStack(sig
uint32) {
430 println("signal", sig
, "received but handler not on signal stack")
431 throw("non-Go code set up signal handler without SA_ONSTACK flag")
434 // This runs on a foreign stack, without an m or a g. No stack split.
437 //go:nowritebarrierrec
438 func badsignal(sig
uintptr, c
*sigctxt
) {
440 if !sigsend(uint32(sig
)) {
441 // A foreign thread received the signal sig, and the
442 // Go code does not want to handle it.
443 raisebadsignal(uint32(sig
), c
)
448 // Determines if the signal should be handled by Go and if not, forwards the
449 // signal to the handler that was installed before Go's. Returns whether the
450 // signal was forwarded.
451 // This is called by the signal handler, and the world may be stopped.
453 //go:nowritebarrierrec
454 func sigfwdgo(sig
uint32, info
*_siginfo_t
, ctx unsafe
.Pointer
) bool {
455 if sig
>= uint32(len(sigtable
)) {
461 // The only way we can get here is if we are in a
462 // library or archive, we installed a signal handler
463 // at program startup, but the Go runtime has not yet
465 if fwdFn
== _SIG_DFL
{
468 sigfwd(fwdFn
, sig
, info
, ctx
)
473 flags
:= sigtable
[sig
].flags
475 // If there is no handler to forward to, no need to forward.
476 if fwdFn
== _SIG_DFL
{
480 // If we aren't handling the signal, forward it.
481 if flags
&_SigHandling
== 0 {
482 sigfwd(fwdFn
, sig
, info
, ctx
)
486 // Only forward synchronous signals.
487 c
:= sigctxt
{info
, ctx
}
488 if c
.sigcode() == _SI_USER || flags
&_SigPanic
== 0 {
491 // Determine if the signal occurred inside Go code. We test that:
492 // (1) we were in a goroutine (i.e., m.curg != nil), and
493 // (2) we weren't in CGO (i.e., m.curg.syscallsp == 0).
495 if g
!= nil && g
.m
!= nil && g
.m
.curg
!= nil && g
.m
.curg
.syscallsp
== 0 {
498 // Signal not handled by Go, forward it.
499 if fwdFn
!= _SIG_IGN
{
500 sigfwd(fwdFn
, sig
, info
, ctx
)
505 // msigsave saves the current thread's signal mask into mp.sigmask.
506 // This is used to preserve the non-Go signal mask when a non-Go
507 // thread calls a Go function.
508 // This is nosplit and nowritebarrierrec because it is called by needm
509 // which may be called on a non-Go thread with no g available.
511 //go:nowritebarrierrec
512 func msigsave(mp
*m
) {
513 sigprocmask(_SIG_SETMASK
, nil, &mp
.sigmask
)
516 // msigrestore sets the current thread's signal mask to sigmask.
517 // This is used to restore the non-Go signal mask when a non-Go thread
518 // calls a Go function.
519 // This is nosplit and nowritebarrierrec because it is called by dropm
520 // after g has been cleared.
522 //go:nowritebarrierrec
523 func msigrestore(sigmask sigset
) {
524 sigprocmask(_SIG_SETMASK
, &sigmask
, nil)
527 // sigblock blocks all signals in the current thread's signal mask.
528 // This is used to block signals while setting up and tearing down g
529 // when a non-Go thread calls a Go function.
530 // The OS-specific code is expected to define sigset_all.
531 // This is nosplit and nowritebarrierrec because it is called by needm
532 // which may be called on a non-Go thread with no g available.
534 //go:nowritebarrierrec
538 sigprocmask(_SIG_SETMASK
, &set
, nil)
541 // unblocksig removes sig from the current thread's signal mask.
542 // This is nosplit and nowritebarrierrec because it is called from
543 // dieFromSignal, which can be called by sigfwdgo while running in the
544 // signal handler, on the signal stack, with no g available.
546 //go:nowritebarrierrec
547 func unblocksig(sig
uint32) {
550 sigaddset(&set
, int(sig
))
551 sigprocmask(_SIG_UNBLOCK
, &set
, nil)
554 // minitSignals is called when initializing a new m to set the
555 // thread's alternate signal stack and signal mask.
556 func minitSignals() {
561 // minitSignalStack is called when initializing a new m to set the
562 // alternate signal stack. If the alternate signal stack is not set
563 // for the thread (the normal case) then set the alternate signal
564 // stack to the gsignal stack. If the alternate signal stack is set
565 // for the thread (the case when a non-Go thread sets the alternate
566 // signal stack and then calls a Go function) then set the gsignal
567 // stack to the alternate signal stack. Record which choice was made
568 // in newSigstack, so that it can be undone in unminit.
569 func minitSignalStack() {
572 sigaltstack(nil, &st
)
573 if st
.ss_flags
&_SS_DISABLE
!= 0 {
574 signalstack(_g_
.m
.gsignalstack
, _g_
.m
.gsignalstacksize
)
575 _g_
.m
.newSigstack
= true
577 _g_
.m
.newSigstack
= false
581 // minitSignalMask is called when initializing a new m to set the
582 // thread's signal mask. When this is called all signals have been
583 // blocked for the thread. This starts with m.sigmask, which was set
584 // either from initSigmask for a newly created thread or by calling
585 // msigsave if this is a non-Go thread calling a Go function. It
586 // removes all essential signals from the mask, thus causing those
587 // signals to not be blocked. Then it sets the thread's signal mask.
588 // After this is called the thread can receive signals.
589 func minitSignalMask() {
590 nmask
:= getg().m
.sigmask
591 for i
:= range sigtable
{
592 if sigtable
[i
].flags
&_SigUnblock
!= 0 {
596 sigprocmask(_SIG_SETMASK
, &nmask
, nil)
599 // unminitSignals is called from dropm, via unminit, to undo the
600 // effect of calling minit on a non-Go thread.
602 func unminitSignals() {
603 if getg().m
.newSigstack
{