github.com/fenixara/go@v0.0.0-20170127160404-96ea0918e670/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 setStack := false 216 var gsignalStack gsignalStack 217 sp := uintptr(unsafe.Pointer(&sig)) 218 if sp < g.m.gsignal.stack.lo || sp >= g.m.gsignal.stack.hi { 219 if sp >= g.m.g0.stack.lo && sp < g.m.g0.stack.hi { 220 // The signal was delivered on the g0 stack. 221 // This can happen when linked with C code 222 // using the thread sanitizer, which collects 223 // signals then delivers them itself by calling 224 // the signal handler directly when C code, 225 // including C code called via cgo, calls a 226 // TSAN-intercepted function such as malloc. 227 st := stackt{ss_size: g.m.g0.stack.hi - g.m.g0.stack.lo} 228 setSignalstackSP(&st, g.m.g0.stack.lo) 229 setGsignalStack(&st, &gsignalStack) 230 g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) 231 setStack = true 232 } else { 233 var st stackt 234 sigaltstack(nil, &st) 235 if st.ss_flags&_SS_DISABLE != 0 { 236 setg(nil) 237 needm(0) 238 noSignalStack(sig) 239 dropm() 240 } 241 stsp := uintptr(unsafe.Pointer(st.ss_sp)) 242 if sp < stsp || sp >= stsp+st.ss_size { 243 setg(nil) 244 needm(0) 245 sigNotOnStack(sig) 246 dropm() 247 } 248 setGsignalStack(&st, &gsignalStack) 249 g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) 250 setStack = true 251 } 252 } 253 254 setg(g.m.gsignal) 255 c := &sigctxt{info, ctx} 256 c.fixsigcode(sig) 257 sighandler(sig, info, ctx, g) 258 setg(g) 259 if setStack { 260 restoreGsignalStack(&gsignalStack) 261 } 262 } 263 264 // sigpanic turns a synchronous signal into a run-time panic. 265 // If the signal handler sees a synchronous panic, it arranges the 266 // stack to look like the function where the signal occurred called 267 // sigpanic, sets the signal's PC value to sigpanic, and returns from 268 // the signal handler. The effect is that the program will act as 269 // though the function that got the signal simply called sigpanic 270 // instead. 271 func sigpanic() { 272 g := getg() 273 if !canpanic(g) { 274 throw("unexpected signal during runtime execution") 275 } 276 277 switch g.sig { 278 case _SIGBUS: 279 if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 { 280 panicmem() 281 } 282 // Support runtime/debug.SetPanicOnFault. 283 if g.paniconfault { 284 panicmem() 285 } 286 print("unexpected fault address ", hex(g.sigcode1), "\n") 287 throw("fault") 288 case _SIGSEGV: 289 if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 { 290 panicmem() 291 } 292 // Support runtime/debug.SetPanicOnFault. 293 if g.paniconfault { 294 panicmem() 295 } 296 print("unexpected fault address ", hex(g.sigcode1), "\n") 297 throw("fault") 298 case _SIGFPE: 299 switch g.sigcode0 { 300 case _FPE_INTDIV: 301 panicdivide() 302 case _FPE_INTOVF: 303 panicoverflow() 304 } 305 panicfloat() 306 } 307 308 if g.sig >= uint32(len(sigtable)) { 309 // can't happen: we looked up g.sig in sigtable to decide to call sigpanic 310 throw("unexpected signal value") 311 } 312 panic(errorString(sigtable[g.sig].name)) 313 } 314 315 // dieFromSignal kills the program with a signal. 316 // This provides the expected exit status for the shell. 317 // This is only called with fatal signals expected to kill the process. 318 //go:nosplit 319 //go:nowritebarrierrec 320 func dieFromSignal(sig uint32) { 321 setsig(sig, _SIG_DFL) 322 unblocksig(sig) 323 raise(sig) 324 325 // That should have killed us. On some systems, though, raise 326 // sends the signal to the whole process rather than to just 327 // the current thread, which means that the signal may not yet 328 // have been delivered. Give other threads a chance to run and 329 // pick up the signal. 330 osyield() 331 osyield() 332 osyield() 333 334 // If we are still somehow running, just exit with the wrong status. 335 exit(2) 336 } 337 338 // raisebadsignal is called when a signal is received on a non-Go 339 // thread, and the Go program does not want to handle it (that is, the 340 // program has not called os/signal.Notify for the signal). 341 func raisebadsignal(sig uint32, c *sigctxt) { 342 if sig == _SIGPROF { 343 // Ignore profiling signals that arrive on non-Go threads. 344 return 345 } 346 347 var handler uintptr 348 if sig >= _NSIG { 349 handler = _SIG_DFL 350 } else { 351 handler = fwdSig[sig] 352 } 353 354 // Reset the signal handler and raise the signal. 355 // We are currently running inside a signal handler, so the 356 // signal is blocked. We need to unblock it before raising the 357 // signal, or the signal we raise will be ignored until we return 358 // from the signal handler. We know that the signal was unblocked 359 // before entering the handler, or else we would not have received 360 // it. That means that we don't have to worry about blocking it 361 // again. 362 unblocksig(sig) 363 setsig(sig, handler) 364 365 // If we're linked into a non-Go program we want to try to 366 // avoid modifying the original context in which the signal 367 // was raised. If the handler is the default, we know it 368 // is non-recoverable, so we don't have to worry about 369 // re-installing sighandler. At this point we can just 370 // return and the signal will be re-raised and caught by 371 // the default handler with the correct context. 372 if (isarchive || islibrary) && handler == _SIG_DFL && c.sigcode() != _SI_USER { 373 return 374 } 375 376 raise(sig) 377 378 // Give the signal a chance to be delivered. 379 // In almost all real cases the program is about to crash, 380 // so sleeping here is not a waste of time. 381 usleep(1000) 382 383 // If the signal didn't cause the program to exit, restore the 384 // Go signal handler and carry on. 385 // 386 // We may receive another instance of the signal before we 387 // restore the Go handler, but that is not so bad: we know 388 // that the Go program has been ignoring the signal. 389 setsig(sig, funcPC(sighandler)) 390 } 391 392 func crash() { 393 if GOOS == "darwin" { 394 // OS X core dumps are linear dumps of the mapped memory, 395 // from the first virtual byte to the last, with zeros in the gaps. 396 // Because of the way we arrange the address space on 64-bit systems, 397 // this means the OS X core file will be >128 GB and even on a zippy 398 // workstation can take OS X well over an hour to write (uninterruptible). 399 // Save users from making that mistake. 400 if sys.PtrSize == 8 { 401 return 402 } 403 } 404 405 dieFromSignal(_SIGABRT) 406 } 407 408 // ensureSigM starts one global, sleeping thread to make sure at least one thread 409 // is available to catch signals enabled for os/signal. 410 func ensureSigM() { 411 if maskUpdatedChan != nil { 412 return 413 } 414 maskUpdatedChan = make(chan struct{}) 415 disableSigChan = make(chan uint32) 416 enableSigChan = make(chan uint32) 417 go func() { 418 // Signal masks are per-thread, so make sure this goroutine stays on one 419 // thread. 420 LockOSThread() 421 defer UnlockOSThread() 422 // The sigBlocked mask contains the signals not active for os/signal, 423 // initially all signals except the essential. When signal.Notify()/Stop is called, 424 // sigenable/sigdisable in turn notify this thread to update its signal 425 // mask accordingly. 426 sigBlocked := sigset_all 427 for i := range sigtable { 428 if sigtable[i].flags&_SigUnblock != 0 { 429 sigdelset(&sigBlocked, i) 430 } 431 } 432 sigprocmask(_SIG_SETMASK, &sigBlocked, nil) 433 for { 434 select { 435 case sig := <-enableSigChan: 436 if sig > 0 { 437 sigdelset(&sigBlocked, int(sig)) 438 } 439 case sig := <-disableSigChan: 440 if sig > 0 { 441 sigaddset(&sigBlocked, int(sig)) 442 } 443 } 444 sigprocmask(_SIG_SETMASK, &sigBlocked, nil) 445 maskUpdatedChan <- struct{}{} 446 } 447 }() 448 } 449 450 // This is called when we receive a signal when there is no signal stack. 451 // This can only happen if non-Go code calls sigaltstack to disable the 452 // signal stack. 453 func noSignalStack(sig uint32) { 454 println("signal", sig, "received on thread with no signal stack") 455 throw("non-Go code disabled sigaltstack") 456 } 457 458 // This is called if we receive a signal when there is a signal stack 459 // but we are not on it. This can only happen if non-Go code called 460 // sigaction without setting the SS_ONSTACK flag. 461 func sigNotOnStack(sig uint32) { 462 println("signal", sig, "received but handler not on signal stack") 463 throw("non-Go code set up signal handler without SA_ONSTACK flag") 464 } 465 466 // This runs on a foreign stack, without an m or a g. No stack split. 467 //go:nosplit 468 //go:norace 469 //go:nowritebarrierrec 470 func badsignal(sig uintptr, c *sigctxt) { 471 needm(0) 472 if !sigsend(uint32(sig)) { 473 // A foreign thread received the signal sig, and the 474 // Go code does not want to handle it. 475 raisebadsignal(uint32(sig), c) 476 } 477 dropm() 478 } 479 480 //go:noescape 481 func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer) 482 483 // Determines if the signal should be handled by Go and if not, forwards the 484 // signal to the handler that was installed before Go's. Returns whether the 485 // signal was forwarded. 486 // This is called by the signal handler, and the world may be stopped. 487 //go:nosplit 488 //go:nowritebarrierrec 489 func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool { 490 if sig >= uint32(len(sigtable)) { 491 return false 492 } 493 fwdFn := fwdSig[sig] 494 495 if !signalsOK { 496 // The only way we can get here is if we are in a 497 // library or archive, we installed a signal handler 498 // at program startup, but the Go runtime has not yet 499 // been initialized. 500 if fwdFn == _SIG_DFL { 501 dieFromSignal(sig) 502 } else { 503 sigfwd(fwdFn, sig, info, ctx) 504 } 505 return true 506 } 507 508 flags := sigtable[sig].flags 509 510 // If there is no handler to forward to, no need to forward. 511 if fwdFn == _SIG_DFL { 512 return false 513 } 514 515 // If we aren't handling the signal, forward it. 516 if flags&_SigHandling == 0 { 517 sigfwd(fwdFn, sig, info, ctx) 518 return true 519 } 520 521 // Only forward synchronous signals. 522 c := &sigctxt{info, ctx} 523 if c.sigcode() == _SI_USER || flags&_SigPanic == 0 { 524 return false 525 } 526 // Determine if the signal occurred inside Go code. We test that: 527 // (1) we were in a goroutine (i.e., m.curg != nil), and 528 // (2) we weren't in CGO (i.e., m.curg.syscallsp == 0). 529 g := getg() 530 if g != nil && g.m != nil && g.m.curg != nil && g.m.curg.syscallsp == 0 { 531 return false 532 } 533 // Signal not handled by Go, forward it. 534 if fwdFn != _SIG_IGN { 535 sigfwd(fwdFn, sig, info, ctx) 536 } 537 return true 538 } 539 540 // msigsave saves the current thread's signal mask into mp.sigmask. 541 // This is used to preserve the non-Go signal mask when a non-Go 542 // thread calls a Go function. 543 // This is nosplit and nowritebarrierrec because it is called by needm 544 // which may be called on a non-Go thread with no g available. 545 //go:nosplit 546 //go:nowritebarrierrec 547 func msigsave(mp *m) { 548 sigprocmask(_SIG_SETMASK, nil, &mp.sigmask) 549 } 550 551 // msigrestore sets the current thread's signal mask to sigmask. 552 // This is used to restore the non-Go signal mask when a non-Go thread 553 // calls a Go function. 554 // This is nosplit and nowritebarrierrec because it is called by dropm 555 // after g has been cleared. 556 //go:nosplit 557 //go:nowritebarrierrec 558 func msigrestore(sigmask sigset) { 559 sigprocmask(_SIG_SETMASK, &sigmask, nil) 560 } 561 562 // sigblock blocks all signals in the current thread's signal mask. 563 // This is used to block signals while setting up and tearing down g 564 // when a non-Go thread calls a Go function. 565 // The OS-specific code is expected to define sigset_all. 566 // This is nosplit and nowritebarrierrec because it is called by needm 567 // which may be called on a non-Go thread with no g available. 568 //go:nosplit 569 //go:nowritebarrierrec 570 func sigblock() { 571 sigprocmask(_SIG_SETMASK, &sigset_all, nil) 572 } 573 574 // unblocksig removes sig from the current thread's signal mask. 575 // This is nosplit and nowritebarrierrec because it is called from 576 // dieFromSignal, which can be called by sigfwdgo while running in the 577 // signal handler, on the signal stack, with no g available. 578 //go:nosplit 579 //go:nowritebarrierrec 580 func unblocksig(sig uint32) { 581 var set sigset 582 sigaddset(&set, int(sig)) 583 sigprocmask(_SIG_UNBLOCK, &set, nil) 584 } 585 586 // minitSignals is called when initializing a new m to set the 587 // thread's alternate signal stack and signal mask. 588 func minitSignals() { 589 minitSignalStack() 590 minitSignalMask() 591 } 592 593 // minitSignalStack is called when initializing a new m to set the 594 // alternate signal stack. If the alternate signal stack is not set 595 // for the thread (the normal case) then set the alternate signal 596 // stack to the gsignal stack. If the alternate signal stack is set 597 // for the thread (the case when a non-Go thread sets the alternate 598 // signal stack and then calls a Go function) then set the gsignal 599 // stack to the alternate signal stack. Record which choice was made 600 // in newSigstack, so that it can be undone in unminit. 601 func minitSignalStack() { 602 _g_ := getg() 603 var st stackt 604 sigaltstack(nil, &st) 605 if st.ss_flags&_SS_DISABLE != 0 { 606 signalstack(&_g_.m.gsignal.stack) 607 _g_.m.newSigstack = true 608 } else { 609 setGsignalStack(&st, nil) 610 _g_.m.newSigstack = false 611 } 612 } 613 614 // minitSignalMask is called when initializing a new m to set the 615 // thread's signal mask. When this is called all signals have been 616 // blocked for the thread. This starts with m.sigmask, which was set 617 // either from initSigmask for a newly created thread or by calling 618 // msigsave if this is a non-Go thread calling a Go function. It 619 // removes all essential signals from the mask, thus causing those 620 // signals to not be blocked. Then it sets the thread's signal mask. 621 // After this is called the thread can receive signals. 622 func minitSignalMask() { 623 nmask := getg().m.sigmask 624 for i := range sigtable { 625 if sigtable[i].flags&_SigUnblock != 0 { 626 sigdelset(&nmask, i) 627 } 628 } 629 sigprocmask(_SIG_SETMASK, &nmask, nil) 630 } 631 632 // unminitSignals is called from dropm, via unminit, to undo the 633 // effect of calling minit on a non-Go thread. 634 //go:nosplit 635 func unminitSignals() { 636 if getg().m.newSigstack { 637 st := stackt{ss_flags: _SS_DISABLE} 638 sigaltstack(&st, nil) 639 } 640 } 641 642 // gsignalStack saves the fields of the gsignal stack changed by 643 // setGsignalStack. 644 type gsignalStack struct { 645 stack stack 646 stackguard0 uintptr 647 stackguard1 uintptr 648 stackAlloc uintptr 649 stktopsp uintptr 650 } 651 652 // setGsignalStack sets the gsignal stack of the current m to an 653 // alternate signal stack returned from the sigaltstack system call. 654 // It saves the old values in *old for use by restoreGsignalStack. 655 // This is used when handling a signal if non-Go code has set the 656 // alternate signal stack. 657 //go:nosplit 658 //go:nowritebarrierrec 659 func setGsignalStack(st *stackt, old *gsignalStack) { 660 g := getg() 661 if old != nil { 662 old.stack = g.m.gsignal.stack 663 old.stackguard0 = g.m.gsignal.stackguard0 664 old.stackguard1 = g.m.gsignal.stackguard1 665 old.stackAlloc = g.m.gsignal.stackAlloc 666 old.stktopsp = g.m.gsignal.stktopsp 667 } 668 stsp := uintptr(unsafe.Pointer(st.ss_sp)) 669 g.m.gsignal.stack.lo = stsp 670 g.m.gsignal.stack.hi = stsp + st.ss_size 671 g.m.gsignal.stackguard0 = stsp + _StackGuard 672 g.m.gsignal.stackguard1 = stsp + _StackGuard 673 g.m.gsignal.stackAlloc = st.ss_size 674 } 675 676 // restoreGsignalStack restores the gsignal stack to the value it had 677 // before entering the signal handler. 678 //go:nosplit 679 //go:nowritebarrierrec 680 func restoreGsignalStack(st *gsignalStack) { 681 gp := getg().m.gsignal 682 gp.stack = st.stack 683 gp.stackguard0 = st.stackguard0 684 gp.stackguard1 = st.stackguard1 685 gp.stackAlloc = st.stackAlloc 686 gp.stktopsp = st.stktopsp 687 } 688 689 // signalstack sets the current thread's alternate signal stack to s. 690 //go:nosplit 691 func signalstack(s *stack) { 692 st := stackt{ss_size: s.hi - s.lo} 693 setSignalstackSP(&st, s.lo) 694 sigaltstack(&st, nil) 695 } 696 697 // setsigsegv is used on darwin/arm{,64} to fake a segmentation fault. 698 //go:nosplit 699 func setsigsegv(pc uintptr) { 700 g := getg() 701 g.sig = _SIGSEGV 702 g.sigpc = pc 703 g.sigcode0 = _SEGV_MAPERR 704 g.sigcode1 = 0 // TODO: emulate si_addr 705 }