github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/src/runtime/signal_unix.go (about) 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. 4 5 // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 7 package runtime 8 9 import ( 10 "runtime/internal/sys" 11 "unsafe" 12 ) 13 14 //go:linkname os_sigpipe os.sigpipe 15 func os_sigpipe() { 16 systemstack(sigpipe) 17 } 18 19 func signame(sig uint32) string { 20 if sig >= uint32(len(sigtable)) { 21 return "" 22 } 23 return sigtable[sig].name 24 } 25 26 const ( 27 _SIG_DFL uintptr = 0 28 _SIG_IGN uintptr = 1 29 ) 30 31 // Stores the signal handlers registered before Go installed its own. 32 // These signal handlers will be invoked in cases where Go doesn't want to 33 // handle a particular signal (e.g., signal occurred on a non-Go thread). 34 // See sigfwdgo() for more information on when the signals are forwarded. 35 // 36 // Signal forwarding is currently available only on Darwin and Linux. 37 var fwdSig [_NSIG]uintptr 38 39 // channels for synchronizing signal mask updates with the signal mask 40 // thread 41 var ( 42 disableSigChan chan uint32 43 enableSigChan chan uint32 44 maskUpdatedChan chan struct{} 45 ) 46 47 func init() { 48 // _NSIG is the number of signals on this operating system. 49 // sigtable should describe what to do for all the possible signals. 50 if len(sigtable) != _NSIG { 51 print("runtime: len(sigtable)=", len(sigtable), " _NSIG=", _NSIG, "\n") 52 throw("bad sigtable len") 53 } 54 } 55 56 var signalsOK bool 57 58 // Initialize signals. 59 // Called by libpreinit so runtime may not be initialized. 60 //go:nosplit 61 //go:nowritebarrierrec 62 func initsig(preinit bool) { 63 if !preinit { 64 // It's now OK for signal handlers to run. 65 signalsOK = true 66 } 67 68 // For c-archive/c-shared this is called by libpreinit with 69 // preinit == true. 70 if (isarchive || islibrary) && !preinit { 71 return 72 } 73 74 for i := uint32(0); i < _NSIG; i++ { 75 t := &sigtable[i] 76 if t.flags == 0 || t.flags&_SigDefault != 0 { 77 continue 78 } 79 fwdSig[i] = getsig(i) 80 81 if !sigInstallGoHandler(i) { 82 // Even if we are not installing a signal handler, 83 // set SA_ONSTACK if necessary. 84 if fwdSig[i] != _SIG_DFL && fwdSig[i] != _SIG_IGN { 85 setsigstack(i) 86 } 87 continue 88 } 89 90 t.flags |= _SigHandling 91 setsig(i, funcPC(sighandler)) 92 } 93 } 94 95 //go:nosplit 96 //go:nowritebarrierrec 97 func sigInstallGoHandler(sig uint32) bool { 98 // For some signals, we respect an inherited SIG_IGN handler 99 // rather than insist on installing our own default handler. 100 // Even these signals can be fetched using the os/signal package. 101 switch sig { 102 case _SIGHUP, _SIGINT: 103 if fwdSig[sig] == _SIG_IGN { 104 return false 105 } 106 } 107 108 t := &sigtable[sig] 109 if t.flags&_SigSetStack != 0 { 110 return false 111 } 112 113 // When built using c-archive or c-shared, only install signal 114 // handlers for synchronous signals. 115 if (isarchive || islibrary) && t.flags&_SigPanic == 0 { 116 return false 117 } 118 119 return true 120 } 121 122 func sigenable(sig uint32) { 123 if sig >= uint32(len(sigtable)) { 124 return 125 } 126 127 t := &sigtable[sig] 128 if t.flags&_SigNotify != 0 { 129 ensureSigM() 130 enableSigChan <- sig 131 <-maskUpdatedChan 132 if t.flags&_SigHandling == 0 { 133 t.flags |= _SigHandling 134 fwdSig[sig] = getsig(sig) 135 setsig(sig, funcPC(sighandler)) 136 } 137 } 138 } 139 140 func sigdisable(sig uint32) { 141 if sig >= uint32(len(sigtable)) { 142 return 143 } 144 145 t := &sigtable[sig] 146 if t.flags&_SigNotify != 0 { 147 ensureSigM() 148 disableSigChan <- sig 149 <-maskUpdatedChan 150 151 // If initsig does not install a signal handler for a 152 // signal, then to go back to the state before Notify 153 // we should remove the one we installed. 154 if !sigInstallGoHandler(sig) { 155 t.flags &^= _SigHandling 156 setsig(sig, fwdSig[sig]) 157 } 158 } 159 } 160 161 func sigignore(sig uint32) { 162 if sig >= uint32(len(sigtable)) { 163 return 164 } 165 166 t := &sigtable[sig] 167 if t.flags&_SigNotify != 0 { 168 t.flags &^= _SigHandling 169 setsig(sig, _SIG_IGN) 170 } 171 } 172 173 func resetcpuprofiler(hz int32) { 174 var it itimerval 175 if hz == 0 { 176 setitimer(_ITIMER_PROF, &it, nil) 177 } else { 178 it.it_interval.tv_sec = 0 179 it.it_interval.set_usec(1000000 / hz) 180 it.it_value = it.it_interval 181 setitimer(_ITIMER_PROF, &it, nil) 182 } 183 _g_ := getg() 184 _g_.m.profilehz = hz 185 } 186 187 func sigpipe() { 188 if sigsend(_SIGPIPE) { 189 return 190 } 191 dieFromSignal(_SIGPIPE) 192 } 193 194 // sigtrampgo is called from the signal handler function, sigtramp, 195 // written in assembly code. 196 // This is called by the signal handler, and the world may be stopped. 197 //go:nosplit 198 //go:nowritebarrierrec 199 func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { 200 if sigfwdgo(sig, info, ctx) { 201 return 202 } 203 g := getg() 204 if g == nil { 205 c := &sigctxt{info, ctx} 206 if sig == _SIGPROF { 207 sigprofNonGoPC(c.sigpc()) 208 return 209 } 210 badsignal(uintptr(sig), c) 211 return 212 } 213 214 // If some non-Go code called sigaltstack, adjust. 215 sp := uintptr(unsafe.Pointer(&sig)) 216 if sp < g.m.gsignal.stack.lo || sp >= g.m.gsignal.stack.hi { 217 var st stackt 218 sigaltstack(nil, &st) 219 if st.ss_flags&_SS_DISABLE != 0 { 220 setg(nil) 221 needm(0) 222 noSignalStack(sig) 223 dropm() 224 } 225 stsp := uintptr(unsafe.Pointer(st.ss_sp)) 226 if sp < stsp || sp >= stsp+st.ss_size { 227 setg(nil) 228 needm(0) 229 sigNotOnStack(sig) 230 dropm() 231 } 232 setGsignalStack(&st) 233 g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) 234 } 235 236 setg(g.m.gsignal) 237 c := &sigctxt{info, ctx} 238 c.fixsigcode(sig) 239 sighandler(sig, info, ctx, g) 240 setg(g) 241 } 242 243 // sigpanic turns a synchronous signal into a run-time panic. 244 // If the signal handler sees a synchronous panic, it arranges the 245 // stack to look like the function where the signal occurred called 246 // sigpanic, sets the signal's PC value to sigpanic, and returns from 247 // the signal handler. The effect is that the program will act as 248 // though the function that got the signal simply called sigpanic 249 // instead. 250 func sigpanic() { 251 g := getg() 252 if !canpanic(g) { 253 throw("unexpected signal during runtime execution") 254 } 255 256 switch g.sig { 257 case _SIGBUS: 258 if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 { 259 panicmem() 260 } 261 // Support runtime/debug.SetPanicOnFault. 262 if g.paniconfault { 263 panicmem() 264 } 265 print("unexpected fault address ", hex(g.sigcode1), "\n") 266 throw("fault") 267 case _SIGSEGV: 268 if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 { 269 panicmem() 270 } 271 // Support runtime/debug.SetPanicOnFault. 272 if g.paniconfault { 273 panicmem() 274 } 275 print("unexpected fault address ", hex(g.sigcode1), "\n") 276 throw("fault") 277 case _SIGFPE: 278 switch g.sigcode0 { 279 case _FPE_INTDIV: 280 panicdivide() 281 case _FPE_INTOVF: 282 panicoverflow() 283 } 284 panicfloat() 285 } 286 287 if g.sig >= uint32(len(sigtable)) { 288 // can't happen: we looked up g.sig in sigtable to decide to call sigpanic 289 throw("unexpected signal value") 290 } 291 panic(errorString(sigtable[g.sig].name)) 292 } 293 294 // dieFromSignal kills the program with a signal. 295 // This provides the expected exit status for the shell. 296 // This is only called with fatal signals expected to kill the process. 297 //go:nosplit 298 //go:nowritebarrierrec 299 func dieFromSignal(sig uint32) { 300 setsig(sig, _SIG_DFL) 301 unblocksig(sig) 302 raise(sig) 303 304 // That should have killed us. On some systems, though, raise 305 // sends the signal to the whole process rather than to just 306 // the current thread, which means that the signal may not yet 307 // have been delivered. Give other threads a chance to run and 308 // pick up the signal. 309 osyield() 310 osyield() 311 osyield() 312 313 // If we are still somehow running, just exit with the wrong status. 314 exit(2) 315 } 316 317 // raisebadsignal is called when a signal is received on a non-Go 318 // thread, and the Go program does not want to handle it (that is, the 319 // program has not called os/signal.Notify for the signal). 320 func raisebadsignal(sig uint32, c *sigctxt) { 321 if sig == _SIGPROF { 322 // Ignore profiling signals that arrive on non-Go threads. 323 return 324 } 325 326 var handler uintptr 327 if sig >= _NSIG { 328 handler = _SIG_DFL 329 } else { 330 handler = fwdSig[sig] 331 } 332 333 // Reset the signal handler and raise the signal. 334 // We are currently running inside a signal handler, so the 335 // signal is blocked. We need to unblock it before raising the 336 // signal, or the signal we raise will be ignored until we return 337 // from the signal handler. We know that the signal was unblocked 338 // before entering the handler, or else we would not have received 339 // it. That means that we don't have to worry about blocking it 340 // again. 341 unblocksig(sig) 342 setsig(sig, handler) 343 344 // If we're linked into a non-Go program we want to try to 345 // avoid modifying the original context in which the signal 346 // was raised. If the handler is the default, we know it 347 // is non-recoverable, so we don't have to worry about 348 // re-installing sighandler. At this point we can just 349 // return and the signal will be re-raised and caught by 350 // the default handler with the correct context. 351 if (isarchive || islibrary) && handler == _SIG_DFL && c.sigcode() != _SI_USER { 352 return 353 } 354 355 raise(sig) 356 357 // If the signal didn't cause the program to exit, restore the 358 // Go signal handler and carry on. 359 // 360 // We may receive another instance of the signal before we 361 // restore the Go handler, but that is not so bad: we know 362 // that the Go program has been ignoring the signal. 363 setsig(sig, funcPC(sighandler)) 364 } 365 366 func crash() { 367 if GOOS == "darwin" { 368 // OS X core dumps are linear dumps of the mapped memory, 369 // from the first virtual byte to the last, with zeros in the gaps. 370 // Because of the way we arrange the address space on 64-bit systems, 371 // this means the OS X core file will be >128 GB and even on a zippy 372 // workstation can take OS X well over an hour to write (uninterruptible). 373 // Save users from making that mistake. 374 if sys.PtrSize == 8 { 375 return 376 } 377 } 378 379 dieFromSignal(_SIGABRT) 380 } 381 382 // ensureSigM starts one global, sleeping thread to make sure at least one thread 383 // is available to catch signals enabled for os/signal. 384 func ensureSigM() { 385 if maskUpdatedChan != nil { 386 return 387 } 388 maskUpdatedChan = make(chan struct{}) 389 disableSigChan = make(chan uint32) 390 enableSigChan = make(chan uint32) 391 go func() { 392 // Signal masks are per-thread, so make sure this goroutine stays on one 393 // thread. 394 LockOSThread() 395 defer UnlockOSThread() 396 // The sigBlocked mask contains the signals not active for os/signal, 397 // initially all signals except the essential. When signal.Notify()/Stop is called, 398 // sigenable/sigdisable in turn notify this thread to update its signal 399 // mask accordingly. 400 sigBlocked := sigset_all 401 for i := range sigtable { 402 if sigtable[i].flags&_SigUnblock != 0 { 403 sigdelset(&sigBlocked, i) 404 } 405 } 406 sigprocmask(_SIG_SETMASK, &sigBlocked, nil) 407 for { 408 select { 409 case sig := <-enableSigChan: 410 if sig > 0 { 411 sigdelset(&sigBlocked, int(sig)) 412 } 413 case sig := <-disableSigChan: 414 if sig > 0 { 415 sigaddset(&sigBlocked, int(sig)) 416 } 417 } 418 sigprocmask(_SIG_SETMASK, &sigBlocked, nil) 419 maskUpdatedChan <- struct{}{} 420 } 421 }() 422 } 423 424 // This is called when we receive a signal when there is no signal stack. 425 // This can only happen if non-Go code calls sigaltstack to disable the 426 // signal stack. 427 func noSignalStack(sig uint32) { 428 println("signal", sig, "received on thread with no signal stack") 429 throw("non-Go code disabled sigaltstack") 430 } 431 432 // This is called if we receive a signal when there is a signal stack 433 // but we are not on it. This can only happen if non-Go code called 434 // sigaction without setting the SS_ONSTACK flag. 435 func sigNotOnStack(sig uint32) { 436 println("signal", sig, "received but handler not on signal stack") 437 throw("non-Go code set up signal handler without SA_ONSTACK flag") 438 } 439 440 // This runs on a foreign stack, without an m or a g. No stack split. 441 //go:nosplit 442 //go:norace 443 //go:nowritebarrierrec 444 func badsignal(sig uintptr, c *sigctxt) { 445 needm(0) 446 if !sigsend(uint32(sig)) { 447 // A foreign thread received the signal sig, and the 448 // Go code does not want to handle it. 449 raisebadsignal(uint32(sig), c) 450 } 451 dropm() 452 } 453 454 //go:noescape 455 func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer) 456 457 // Determines if the signal should be handled by Go and if not, forwards the 458 // signal to the handler that was installed before Go's. Returns whether the 459 // signal was forwarded. 460 // This is called by the signal handler, and the world may be stopped. 461 //go:nosplit 462 //go:nowritebarrierrec 463 func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool { 464 if sig >= uint32(len(sigtable)) { 465 return false 466 } 467 fwdFn := fwdSig[sig] 468 469 if !signalsOK { 470 // The only way we can get here is if we are in a 471 // library or archive, we installed a signal handler 472 // at program startup, but the Go runtime has not yet 473 // been initialized. 474 if fwdFn == _SIG_DFL { 475 dieFromSignal(sig) 476 } else { 477 sigfwd(fwdFn, sig, info, ctx) 478 } 479 return true 480 } 481 482 flags := sigtable[sig].flags 483 484 // If there is no handler to forward to, no need to forward. 485 if fwdFn == _SIG_DFL { 486 return false 487 } 488 489 // If we aren't handling the signal, forward it. 490 if flags&_SigHandling == 0 { 491 sigfwd(fwdFn, sig, info, ctx) 492 return true 493 } 494 495 // Only forward synchronous signals. 496 c := &sigctxt{info, ctx} 497 if c.sigcode() == _SI_USER || flags&_SigPanic == 0 { 498 return false 499 } 500 // Determine if the signal occurred inside Go code. We test that: 501 // (1) we were in a goroutine (i.e., m.curg != nil), and 502 // (2) we weren't in CGO (i.e., m.curg.syscallsp == 0). 503 g := getg() 504 if g != nil && g.m != nil && g.m.curg != nil && g.m.curg.syscallsp == 0 { 505 return false 506 } 507 // Signal not handled by Go, forward it. 508 if fwdFn != _SIG_IGN { 509 sigfwd(fwdFn, sig, info, ctx) 510 } 511 return true 512 } 513 514 // msigsave saves the current thread's signal mask into mp.sigmask. 515 // This is used to preserve the non-Go signal mask when a non-Go 516 // thread calls a Go function. 517 // This is nosplit and nowritebarrierrec because it is called by needm 518 // which may be called on a non-Go thread with no g available. 519 //go:nosplit 520 //go:nowritebarrierrec 521 func msigsave(mp *m) { 522 sigprocmask(_SIG_SETMASK, nil, &mp.sigmask) 523 } 524 525 // msigrestore sets the current thread's signal mask to sigmask. 526 // This is used to restore the non-Go signal mask when a non-Go thread 527 // calls a Go function. 528 // This is nosplit and nowritebarrierrec because it is called by dropm 529 // after g has been cleared. 530 //go:nosplit 531 //go:nowritebarrierrec 532 func msigrestore(sigmask sigset) { 533 sigprocmask(_SIG_SETMASK, &sigmask, nil) 534 } 535 536 // sigblock blocks all signals in the current thread's signal mask. 537 // This is used to block signals while setting up and tearing down g 538 // when a non-Go thread calls a Go function. 539 // The OS-specific code is expected to define sigset_all. 540 // This is nosplit and nowritebarrierrec because it is called by needm 541 // which may be called on a non-Go thread with no g available. 542 //go:nosplit 543 //go:nowritebarrierrec 544 func sigblock() { 545 sigprocmask(_SIG_SETMASK, &sigset_all, nil) 546 } 547 548 // unblocksig removes sig from the current thread's signal mask. 549 // This is nosplit and nowritebarrierrec because it is called from 550 // dieFromSignal, which can be called by sigfwdgo while running in the 551 // signal handler, on the signal stack, with no g available. 552 //go:nosplit 553 //go:nowritebarrierrec 554 func unblocksig(sig uint32) { 555 var set sigset 556 sigaddset(&set, int(sig)) 557 sigprocmask(_SIG_UNBLOCK, &set, nil) 558 } 559 560 // minitSignals is called when initializing a new m to set the 561 // thread's alternate signal stack and signal mask. 562 func minitSignals() { 563 minitSignalStack() 564 minitSignalMask() 565 } 566 567 // minitSignalStack is called when initializing a new m to set the 568 // alternate signal stack. If the alternate signal stack is not set 569 // for the thread (the normal case) then set the alternate signal 570 // stack to the gsignal stack. If the alternate signal stack is set 571 // for the thread (the case when a non-Go thread sets the alternate 572 // signal stack and then calls a Go function) then set the gsignal 573 // stack to the alternate signal stack. Record which choice was made 574 // in newSigstack, so that it can be undone in unminit. 575 func minitSignalStack() { 576 _g_ := getg() 577 var st stackt 578 sigaltstack(nil, &st) 579 if st.ss_flags&_SS_DISABLE != 0 { 580 signalstack(&_g_.m.gsignal.stack) 581 _g_.m.newSigstack = true 582 } else { 583 setGsignalStack(&st) 584 _g_.m.newSigstack = false 585 } 586 } 587 588 // minitSignalMask is called when initializing a new m to set the 589 // thread's signal mask. When this is called all signals have been 590 // blocked for the thread. This starts with m.sigmask, which was set 591 // either from initSigmask for a newly created thread or by calling 592 // msigsave if this is a non-Go thread calling a Go function. It 593 // removes all essential signals from the mask, thus causing those 594 // signals to not be blocked. Then it sets the thread's signal mask. 595 // After this is called the thread can receive signals. 596 func minitSignalMask() { 597 nmask := getg().m.sigmask 598 for i := range sigtable { 599 if sigtable[i].flags&_SigUnblock != 0 { 600 sigdelset(&nmask, i) 601 } 602 } 603 sigprocmask(_SIG_SETMASK, &nmask, nil) 604 } 605 606 // unminitSignals is called from dropm, via unminit, to undo the 607 // effect of calling minit on a non-Go thread. 608 //go:nosplit 609 func unminitSignals() { 610 if getg().m.newSigstack { 611 st := stackt{ss_flags: _SS_DISABLE} 612 sigaltstack(&st, nil) 613 } 614 } 615 616 // setGsignalStack sets the gsignal stack of the current m to an 617 // alternate signal stack returned from the sigaltstack system call. 618 // This is used when handling a signal if non-Go code has set the 619 // alternate signal stack. 620 //go:nosplit 621 //go:nowritebarrierrec 622 func setGsignalStack(st *stackt) { 623 g := getg() 624 stsp := uintptr(unsafe.Pointer(st.ss_sp)) 625 g.m.gsignal.stack.lo = stsp 626 g.m.gsignal.stack.hi = stsp + st.ss_size 627 g.m.gsignal.stackguard0 = stsp + _StackGuard 628 g.m.gsignal.stackguard1 = stsp + _StackGuard 629 g.m.gsignal.stackAlloc = st.ss_size 630 } 631 632 // signalstack sets the current thread's alternate signal stack to s. 633 //go:nosplit 634 func signalstack(s *stack) { 635 st := stackt{ss_size: s.hi - s.lo} 636 setSignalstackSP(&st, s.lo) 637 sigaltstack(&st, nil) 638 } 639 640 // setsigsegv is used on darwin/arm{,64} to fake a segmentation fault. 641 //go:nosplit 642 func setsigsegv(pc uintptr) { 643 g := getg() 644 g.sig = _SIGSEGV 645 g.sigpc = pc 646 g.sigcode0 = _SEGV_MAPERR 647 g.sigcode1 = 0 // TODO: emulate si_addr 648 }