golang.org/toolchain@v0.0.1-go1.9rc2.windows-amd64/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/atomic" 11 "runtime/internal/sys" 12 "unsafe" 13 ) 14 15 //go:linkname os_sigpipe os.sigpipe 16 func os_sigpipe() { 17 systemstack(sigpipe) 18 } 19 20 func signame(sig uint32) string { 21 if sig >= uint32(len(sigtable)) { 22 return "" 23 } 24 return sigtable[sig].name 25 } 26 27 const ( 28 _SIG_DFL uintptr = 0 29 _SIG_IGN uintptr = 1 30 ) 31 32 // Stores the signal handlers registered before Go installed its own. 33 // These signal handlers will be invoked in cases where Go doesn't want to 34 // handle a particular signal (e.g., signal occurred on a non-Go thread). 35 // See sigfwdgo for more information on when the signals are forwarded. 36 // 37 // This is read by the signal handler; accesses should use 38 // atomic.Loaduintptr and atomic.Storeuintptr. 39 var fwdSig [_NSIG]uintptr 40 41 // handlingSig is indexed by signal number and is non-zero if we are 42 // currently handling the signal. Or, to put it another way, whether 43 // the signal handler is currently set to the Go signal handler or not. 44 // This is uint32 rather than bool so that we can use atomic instructions. 45 var handlingSig [_NSIG]uint32 46 47 // channels for synchronizing signal mask updates with the signal mask 48 // thread 49 var ( 50 disableSigChan chan uint32 51 enableSigChan chan uint32 52 maskUpdatedChan chan struct{} 53 ) 54 55 func init() { 56 // _NSIG is the number of signals on this operating system. 57 // sigtable should describe what to do for all the possible signals. 58 if len(sigtable) != _NSIG { 59 print("runtime: len(sigtable)=", len(sigtable), " _NSIG=", _NSIG, "\n") 60 throw("bad sigtable len") 61 } 62 } 63 64 var signalsOK bool 65 66 // Initialize signals. 67 // Called by libpreinit so runtime may not be initialized. 68 //go:nosplit 69 //go:nowritebarrierrec 70 func initsig(preinit bool) { 71 if !preinit { 72 // It's now OK for signal handlers to run. 73 signalsOK = true 74 } 75 76 // For c-archive/c-shared this is called by libpreinit with 77 // preinit == true. 78 if (isarchive || islibrary) && !preinit { 79 return 80 } 81 82 for i := uint32(0); i < _NSIG; i++ { 83 t := &sigtable[i] 84 if t.flags == 0 || t.flags&_SigDefault != 0 { 85 continue 86 } 87 88 // We don't need to use atomic operations here because 89 // there shouldn't be any other goroutines running yet. 90 fwdSig[i] = getsig(i) 91 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 { 96 setsigstack(i) 97 } 98 continue 99 } 100 101 handlingSig[i] = 1 102 setsig(i, funcPC(sighandler)) 103 } 104 } 105 106 //go:nosplit 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. 112 switch sig { 113 case _SIGHUP, _SIGINT: 114 if atomic.Loaduintptr(&fwdSig[sig]) == _SIG_IGN { 115 return false 116 } 117 } 118 119 t := &sigtable[sig] 120 if t.flags&_SigSetStack != 0 { 121 return false 122 } 123 124 // When built using c-archive or c-shared, only install signal 125 // handlers for synchronous signals and SIGPIPE. 126 if (isarchive || islibrary) && t.flags&_SigPanic == 0 && sig != _SIGPIPE { 127 return false 128 } 129 130 return true 131 } 132 133 // sigenable enables the Go signal handler to catch the signal sig. 134 // It is only called while holding the os/signal.handlers lock, 135 // via os/signal.enableSignal and signal_enable. 136 func sigenable(sig uint32) { 137 if sig >= uint32(len(sigtable)) { 138 return 139 } 140 141 // SIGPROF is handled specially for profiling. 142 if sig == _SIGPROF { 143 return 144 } 145 146 t := &sigtable[sig] 147 if t.flags&_SigNotify != 0 { 148 ensureSigM() 149 enableSigChan <- sig 150 <-maskUpdatedChan 151 if atomic.Cas(&handlingSig[sig], 0, 1) { 152 atomic.Storeuintptr(&fwdSig[sig], getsig(sig)) 153 setsig(sig, funcPC(sighandler)) 154 } 155 } 156 } 157 158 // sigdisable disables the Go signal handler for the signal sig. 159 // It is only called while holding the os/signal.handlers lock, 160 // via os/signal.disableSignal and signal_disable. 161 func sigdisable(sig uint32) { 162 if sig >= uint32(len(sigtable)) { 163 return 164 } 165 166 // SIGPROF is handled specially for profiling. 167 if sig == _SIGPROF { 168 return 169 } 170 171 t := &sigtable[sig] 172 if t.flags&_SigNotify != 0 { 173 ensureSigM() 174 disableSigChan <- sig 175 <-maskUpdatedChan 176 177 // If initsig does not install a signal handler for a 178 // signal, then to go back to the state before Notify 179 // we should remove the one we installed. 180 if !sigInstallGoHandler(sig) { 181 atomic.Store(&handlingSig[sig], 0) 182 setsig(sig, atomic.Loaduintptr(&fwdSig[sig])) 183 } 184 } 185 } 186 187 // sigignore ignores the signal sig. 188 // It is only called while holding the os/signal.handlers lock, 189 // via os/signal.ignoreSignal and signal_ignore. 190 func sigignore(sig uint32) { 191 if sig >= uint32(len(sigtable)) { 192 return 193 } 194 195 // SIGPROF is handled specially for profiling. 196 if sig == _SIGPROF { 197 return 198 } 199 200 t := &sigtable[sig] 201 if t.flags&_SigNotify != 0 { 202 atomic.Store(&handlingSig[sig], 0) 203 setsig(sig, _SIG_IGN) 204 } 205 } 206 207 // clearSignalHandlers clears all signal handlers that are not ignored 208 // back to the default. This is called by the child after a fork, so that 209 // we can enable the signal mask for the exec without worrying about 210 // running a signal handler in the child. 211 //go:nosplit 212 //go:nowritebarrierrec 213 func clearSignalHandlers() { 214 for i := uint32(0); i < _NSIG; i++ { 215 if atomic.Load(&handlingSig[i]) != 0 { 216 setsig(i, _SIG_DFL) 217 } 218 } 219 } 220 221 // setProcessCPUProfiler is called when the profiling timer changes. 222 // It is called with prof.lock held. hz is the new timer, and is 0 if 223 // profiling is being disabled. Enable or disable the signal as 224 // required for -buildmode=c-archive. 225 func setProcessCPUProfiler(hz int32) { 226 if hz != 0 { 227 // Enable the Go signal handler if not enabled. 228 if atomic.Cas(&handlingSig[_SIGPROF], 0, 1) { 229 atomic.Storeuintptr(&fwdSig[_SIGPROF], getsig(_SIGPROF)) 230 setsig(_SIGPROF, funcPC(sighandler)) 231 } 232 } else { 233 // If the Go signal handler should be disabled by default, 234 // disable it if it is enabled. 235 if !sigInstallGoHandler(_SIGPROF) { 236 if atomic.Cas(&handlingSig[_SIGPROF], 1, 0) { 237 setsig(_SIGPROF, atomic.Loaduintptr(&fwdSig[_SIGPROF])) 238 } 239 } 240 } 241 } 242 243 // setThreadCPUProfiler makes any thread-specific changes required to 244 // implement profiling at a rate of hz. 245 func setThreadCPUProfiler(hz int32) { 246 var it itimerval 247 if hz == 0 { 248 setitimer(_ITIMER_PROF, &it, nil) 249 } else { 250 it.it_interval.tv_sec = 0 251 it.it_interval.set_usec(1000000 / hz) 252 it.it_value = it.it_interval 253 setitimer(_ITIMER_PROF, &it, nil) 254 } 255 _g_ := getg() 256 _g_.m.profilehz = hz 257 } 258 259 func sigpipe() { 260 if sigsend(_SIGPIPE) { 261 return 262 } 263 dieFromSignal(_SIGPIPE) 264 } 265 266 // sigtrampgo is called from the signal handler function, sigtramp, 267 // written in assembly code. 268 // This is called by the signal handler, and the world may be stopped. 269 //go:nosplit 270 //go:nowritebarrierrec 271 func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { 272 if sigfwdgo(sig, info, ctx) { 273 return 274 } 275 g := getg() 276 if g == nil { 277 c := &sigctxt{info, ctx} 278 if sig == _SIGPROF { 279 sigprofNonGoPC(c.sigpc()) 280 return 281 } 282 badsignal(uintptr(sig), c) 283 return 284 } 285 286 // If some non-Go code called sigaltstack, adjust. 287 setStack := false 288 var gsignalStack gsignalStack 289 sp := uintptr(unsafe.Pointer(&sig)) 290 if sp < g.m.gsignal.stack.lo || sp >= g.m.gsignal.stack.hi { 291 if sp >= g.m.g0.stack.lo && sp < g.m.g0.stack.hi { 292 // The signal was delivered on the g0 stack. 293 // This can happen when linked with C code 294 // using the thread sanitizer, which collects 295 // signals then delivers them itself by calling 296 // the signal handler directly when C code, 297 // including C code called via cgo, calls a 298 // TSAN-intercepted function such as malloc. 299 st := stackt{ss_size: g.m.g0.stack.hi - g.m.g0.stack.lo} 300 setSignalstackSP(&st, g.m.g0.stack.lo) 301 setGsignalStack(&st, &gsignalStack) 302 g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) 303 setStack = true 304 } else { 305 var st stackt 306 sigaltstack(nil, &st) 307 if st.ss_flags&_SS_DISABLE != 0 { 308 setg(nil) 309 needm(0) 310 noSignalStack(sig) 311 dropm() 312 } 313 stsp := uintptr(unsafe.Pointer(st.ss_sp)) 314 if sp < stsp || sp >= stsp+st.ss_size { 315 setg(nil) 316 needm(0) 317 sigNotOnStack(sig) 318 dropm() 319 } 320 setGsignalStack(&st, &gsignalStack) 321 g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) 322 setStack = true 323 } 324 } 325 326 setg(g.m.gsignal) 327 328 if g.stackguard0 == stackFork { 329 signalDuringFork(sig) 330 } 331 332 c := &sigctxt{info, ctx} 333 c.fixsigcode(sig) 334 sighandler(sig, info, ctx, g) 335 setg(g) 336 if setStack { 337 restoreGsignalStack(&gsignalStack) 338 } 339 } 340 341 // sigpanic turns a synchronous signal into a run-time panic. 342 // If the signal handler sees a synchronous panic, it arranges the 343 // stack to look like the function where the signal occurred called 344 // sigpanic, sets the signal's PC value to sigpanic, and returns from 345 // the signal handler. The effect is that the program will act as 346 // though the function that got the signal simply called sigpanic 347 // instead. 348 func sigpanic() { 349 g := getg() 350 if !canpanic(g) { 351 throw("unexpected signal during runtime execution") 352 } 353 354 switch g.sig { 355 case _SIGBUS: 356 if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 { 357 panicmem() 358 } 359 // Support runtime/debug.SetPanicOnFault. 360 if g.paniconfault { 361 panicmem() 362 } 363 print("unexpected fault address ", hex(g.sigcode1), "\n") 364 throw("fault") 365 case _SIGSEGV: 366 if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 { 367 panicmem() 368 } 369 // Support runtime/debug.SetPanicOnFault. 370 if g.paniconfault { 371 panicmem() 372 } 373 print("unexpected fault address ", hex(g.sigcode1), "\n") 374 throw("fault") 375 case _SIGFPE: 376 switch g.sigcode0 { 377 case _FPE_INTDIV: 378 panicdivide() 379 case _FPE_INTOVF: 380 panicoverflow() 381 } 382 panicfloat() 383 } 384 385 if g.sig >= uint32(len(sigtable)) { 386 // can't happen: we looked up g.sig in sigtable to decide to call sigpanic 387 throw("unexpected signal value") 388 } 389 panic(errorString(sigtable[g.sig].name)) 390 } 391 392 // dieFromSignal kills the program with a signal. 393 // This provides the expected exit status for the shell. 394 // This is only called with fatal signals expected to kill the process. 395 //go:nosplit 396 //go:nowritebarrierrec 397 func dieFromSignal(sig uint32) { 398 setsig(sig, _SIG_DFL) 399 unblocksig(sig) 400 raise(sig) 401 402 // That should have killed us. On some systems, though, raise 403 // sends the signal to the whole process rather than to just 404 // the current thread, which means that the signal may not yet 405 // have been delivered. Give other threads a chance to run and 406 // pick up the signal. 407 osyield() 408 osyield() 409 osyield() 410 411 // If we are still somehow running, just exit with the wrong status. 412 exit(2) 413 } 414 415 // raisebadsignal is called when a signal is received on a non-Go 416 // thread, and the Go program does not want to handle it (that is, the 417 // program has not called os/signal.Notify for the signal). 418 func raisebadsignal(sig uint32, c *sigctxt) { 419 if sig == _SIGPROF { 420 // Ignore profiling signals that arrive on non-Go threads. 421 return 422 } 423 424 var handler uintptr 425 if sig >= _NSIG { 426 handler = _SIG_DFL 427 } else { 428 handler = atomic.Loaduintptr(&fwdSig[sig]) 429 } 430 431 // Reset the signal handler and raise the signal. 432 // We are currently running inside a signal handler, so the 433 // signal is blocked. We need to unblock it before raising the 434 // signal, or the signal we raise will be ignored until we return 435 // from the signal handler. We know that the signal was unblocked 436 // before entering the handler, or else we would not have received 437 // it. That means that we don't have to worry about blocking it 438 // again. 439 unblocksig(sig) 440 setsig(sig, handler) 441 442 // If we're linked into a non-Go program we want to try to 443 // avoid modifying the original context in which the signal 444 // was raised. If the handler is the default, we know it 445 // is non-recoverable, so we don't have to worry about 446 // re-installing sighandler. At this point we can just 447 // return and the signal will be re-raised and caught by 448 // the default handler with the correct context. 449 if (isarchive || islibrary) && handler == _SIG_DFL && c.sigcode() != _SI_USER { 450 return 451 } 452 453 raise(sig) 454 455 // Give the signal a chance to be delivered. 456 // In almost all real cases the program is about to crash, 457 // so sleeping here is not a waste of time. 458 usleep(1000) 459 460 // If the signal didn't cause the program to exit, restore the 461 // Go signal handler and carry on. 462 // 463 // We may receive another instance of the signal before we 464 // restore the Go handler, but that is not so bad: we know 465 // that the Go program has been ignoring the signal. 466 setsig(sig, funcPC(sighandler)) 467 } 468 469 func crash() { 470 if GOOS == "darwin" { 471 // OS X core dumps are linear dumps of the mapped memory, 472 // from the first virtual byte to the last, with zeros in the gaps. 473 // Because of the way we arrange the address space on 64-bit systems, 474 // this means the OS X core file will be >128 GB and even on a zippy 475 // workstation can take OS X well over an hour to write (uninterruptible). 476 // Save users from making that mistake. 477 if sys.PtrSize == 8 { 478 return 479 } 480 } 481 482 dieFromSignal(_SIGABRT) 483 } 484 485 // ensureSigM starts one global, sleeping thread to make sure at least one thread 486 // is available to catch signals enabled for os/signal. 487 func ensureSigM() { 488 if maskUpdatedChan != nil { 489 return 490 } 491 maskUpdatedChan = make(chan struct{}) 492 disableSigChan = make(chan uint32) 493 enableSigChan = make(chan uint32) 494 go func() { 495 // Signal masks are per-thread, so make sure this goroutine stays on one 496 // thread. 497 LockOSThread() 498 defer UnlockOSThread() 499 // The sigBlocked mask contains the signals not active for os/signal, 500 // initially all signals except the essential. When signal.Notify()/Stop is called, 501 // sigenable/sigdisable in turn notify this thread to update its signal 502 // mask accordingly. 503 sigBlocked := sigset_all 504 for i := range sigtable { 505 if sigtable[i].flags&_SigUnblock != 0 { 506 sigdelset(&sigBlocked, i) 507 } 508 } 509 sigprocmask(_SIG_SETMASK, &sigBlocked, nil) 510 for { 511 select { 512 case sig := <-enableSigChan: 513 if sig > 0 { 514 sigdelset(&sigBlocked, int(sig)) 515 } 516 case sig := <-disableSigChan: 517 if sig > 0 { 518 sigaddset(&sigBlocked, int(sig)) 519 } 520 } 521 sigprocmask(_SIG_SETMASK, &sigBlocked, nil) 522 maskUpdatedChan <- struct{}{} 523 } 524 }() 525 } 526 527 // This is called when we receive a signal when there is no signal stack. 528 // This can only happen if non-Go code calls sigaltstack to disable the 529 // signal stack. 530 func noSignalStack(sig uint32) { 531 println("signal", sig, "received on thread with no signal stack") 532 throw("non-Go code disabled sigaltstack") 533 } 534 535 // This is called if we receive a signal when there is a signal stack 536 // but we are not on it. This can only happen if non-Go code called 537 // sigaction without setting the SS_ONSTACK flag. 538 func sigNotOnStack(sig uint32) { 539 println("signal", sig, "received but handler not on signal stack") 540 throw("non-Go code set up signal handler without SA_ONSTACK flag") 541 } 542 543 // signalDuringFork is called if we receive a signal while doing a fork. 544 // We do not want signals at that time, as a signal sent to the process 545 // group may be delivered to the child process, causing confusion. 546 // This should never be called, because we block signals across the fork; 547 // this function is just a safety check. See issue 18600 for background. 548 func signalDuringFork(sig uint32) { 549 println("signal", sig, "received during fork") 550 throw("signal received during fork") 551 } 552 553 // This runs on a foreign stack, without an m or a g. No stack split. 554 //go:nosplit 555 //go:norace 556 //go:nowritebarrierrec 557 func badsignal(sig uintptr, c *sigctxt) { 558 needm(0) 559 if !sigsend(uint32(sig)) { 560 // A foreign thread received the signal sig, and the 561 // Go code does not want to handle it. 562 raisebadsignal(uint32(sig), c) 563 } 564 dropm() 565 } 566 567 //go:noescape 568 func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer) 569 570 // Determines if the signal should be handled by Go and if not, forwards the 571 // signal to the handler that was installed before Go's. Returns whether the 572 // signal was forwarded. 573 // This is called by the signal handler, and the world may be stopped. 574 //go:nosplit 575 //go:nowritebarrierrec 576 func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool { 577 if sig >= uint32(len(sigtable)) { 578 return false 579 } 580 fwdFn := atomic.Loaduintptr(&fwdSig[sig]) 581 582 if !signalsOK { 583 // The only way we can get here is if we are in a 584 // library or archive, we installed a signal handler 585 // at program startup, but the Go runtime has not yet 586 // been initialized. 587 if fwdFn == _SIG_DFL { 588 dieFromSignal(sig) 589 } else { 590 sigfwd(fwdFn, sig, info, ctx) 591 } 592 return true 593 } 594 595 // If there is no handler to forward to, no need to forward. 596 if fwdFn == _SIG_DFL { 597 return false 598 } 599 600 // If we aren't handling the signal, forward it. 601 // Really if we aren't handling the signal, we shouldn't get here, 602 // but on Darwin setsigstack can lead us here because it sets 603 // the sa_tramp field. The sa_tramp field is not returned by 604 // sigaction, so the fix for that is non-obvious. 605 if atomic.Load(&handlingSig[sig]) == 0 { 606 sigfwd(fwdFn, sig, info, ctx) 607 return true 608 } 609 610 flags := sigtable[sig].flags 611 612 c := &sigctxt{info, ctx} 613 // Only forward synchronous signals and SIGPIPE. 614 // Unfortunately, user generated SIGPIPEs will also be forwarded, because si_code 615 // is set to _SI_USER even for a SIGPIPE raised from a write to a closed socket 616 // or pipe. 617 if (c.sigcode() == _SI_USER || flags&_SigPanic == 0) && sig != _SIGPIPE { 618 return false 619 } 620 // Determine if the signal occurred inside Go code. We test that: 621 // (1) we were in a goroutine (i.e., m.curg != nil), and 622 // (2) we weren't in CGO. 623 g := getg() 624 if g != nil && g.m != nil && g.m.curg != nil && !g.m.incgo { 625 return false 626 } 627 628 // Signal not handled by Go, forward it. 629 if fwdFn != _SIG_IGN { 630 sigfwd(fwdFn, sig, info, ctx) 631 } 632 633 return true 634 } 635 636 // msigsave saves the current thread's signal mask into mp.sigmask. 637 // This is used to preserve the non-Go signal mask when a non-Go 638 // thread calls a Go function. 639 // This is nosplit and nowritebarrierrec because it is called by needm 640 // which may be called on a non-Go thread with no g available. 641 //go:nosplit 642 //go:nowritebarrierrec 643 func msigsave(mp *m) { 644 sigprocmask(_SIG_SETMASK, nil, &mp.sigmask) 645 } 646 647 // msigrestore sets the current thread's signal mask to sigmask. 648 // This is used to restore the non-Go signal mask when a non-Go thread 649 // calls a Go function. 650 // This is nosplit and nowritebarrierrec because it is called by dropm 651 // after g has been cleared. 652 //go:nosplit 653 //go:nowritebarrierrec 654 func msigrestore(sigmask sigset) { 655 sigprocmask(_SIG_SETMASK, &sigmask, nil) 656 } 657 658 // sigblock blocks all signals in the current thread's signal mask. 659 // This is used to block signals while setting up and tearing down g 660 // when a non-Go thread calls a Go function. 661 // The OS-specific code is expected to define sigset_all. 662 // This is nosplit and nowritebarrierrec because it is called by needm 663 // which may be called on a non-Go thread with no g available. 664 //go:nosplit 665 //go:nowritebarrierrec 666 func sigblock() { 667 sigprocmask(_SIG_SETMASK, &sigset_all, nil) 668 } 669 670 // unblocksig removes sig from the current thread's signal mask. 671 // This is nosplit and nowritebarrierrec because it is called from 672 // dieFromSignal, which can be called by sigfwdgo while running in the 673 // signal handler, on the signal stack, with no g available. 674 //go:nosplit 675 //go:nowritebarrierrec 676 func unblocksig(sig uint32) { 677 var set sigset 678 sigaddset(&set, int(sig)) 679 sigprocmask(_SIG_UNBLOCK, &set, nil) 680 } 681 682 // minitSignals is called when initializing a new m to set the 683 // thread's alternate signal stack and signal mask. 684 func minitSignals() { 685 minitSignalStack() 686 minitSignalMask() 687 } 688 689 // minitSignalStack is called when initializing a new m to set the 690 // alternate signal stack. If the alternate signal stack is not set 691 // for the thread (the normal case) then set the alternate signal 692 // stack to the gsignal stack. If the alternate signal stack is set 693 // for the thread (the case when a non-Go thread sets the alternate 694 // signal stack and then calls a Go function) then set the gsignal 695 // stack to the alternate signal stack. Record which choice was made 696 // in newSigstack, so that it can be undone in unminit. 697 func minitSignalStack() { 698 _g_ := getg() 699 var st stackt 700 sigaltstack(nil, &st) 701 if st.ss_flags&_SS_DISABLE != 0 { 702 signalstack(&_g_.m.gsignal.stack) 703 _g_.m.newSigstack = true 704 } else { 705 setGsignalStack(&st, nil) 706 _g_.m.newSigstack = false 707 } 708 } 709 710 // minitSignalMask is called when initializing a new m to set the 711 // thread's signal mask. When this is called all signals have been 712 // blocked for the thread. This starts with m.sigmask, which was set 713 // either from initSigmask for a newly created thread or by calling 714 // msigsave if this is a non-Go thread calling a Go function. It 715 // removes all essential signals from the mask, thus causing those 716 // signals to not be blocked. Then it sets the thread's signal mask. 717 // After this is called the thread can receive signals. 718 func minitSignalMask() { 719 nmask := getg().m.sigmask 720 for i := range sigtable { 721 if sigtable[i].flags&_SigUnblock != 0 { 722 sigdelset(&nmask, i) 723 } 724 } 725 sigprocmask(_SIG_SETMASK, &nmask, nil) 726 } 727 728 // unminitSignals is called from dropm, via unminit, to undo the 729 // effect of calling minit on a non-Go thread. 730 //go:nosplit 731 func unminitSignals() { 732 if getg().m.newSigstack { 733 st := stackt{ss_flags: _SS_DISABLE} 734 sigaltstack(&st, nil) 735 } 736 } 737 738 // gsignalStack saves the fields of the gsignal stack changed by 739 // setGsignalStack. 740 type gsignalStack struct { 741 stack stack 742 stackguard0 uintptr 743 stackguard1 uintptr 744 stktopsp uintptr 745 } 746 747 // setGsignalStack sets the gsignal stack of the current m to an 748 // alternate signal stack returned from the sigaltstack system call. 749 // It saves the old values in *old for use by restoreGsignalStack. 750 // This is used when handling a signal if non-Go code has set the 751 // alternate signal stack. 752 //go:nosplit 753 //go:nowritebarrierrec 754 func setGsignalStack(st *stackt, old *gsignalStack) { 755 g := getg() 756 if old != nil { 757 old.stack = g.m.gsignal.stack 758 old.stackguard0 = g.m.gsignal.stackguard0 759 old.stackguard1 = g.m.gsignal.stackguard1 760 old.stktopsp = g.m.gsignal.stktopsp 761 } 762 stsp := uintptr(unsafe.Pointer(st.ss_sp)) 763 g.m.gsignal.stack.lo = stsp 764 g.m.gsignal.stack.hi = stsp + st.ss_size 765 g.m.gsignal.stackguard0 = stsp + _StackGuard 766 g.m.gsignal.stackguard1 = stsp + _StackGuard 767 } 768 769 // restoreGsignalStack restores the gsignal stack to the value it had 770 // before entering the signal handler. 771 //go:nosplit 772 //go:nowritebarrierrec 773 func restoreGsignalStack(st *gsignalStack) { 774 gp := getg().m.gsignal 775 gp.stack = st.stack 776 gp.stackguard0 = st.stackguard0 777 gp.stackguard1 = st.stackguard1 778 gp.stktopsp = st.stktopsp 779 } 780 781 // signalstack sets the current thread's alternate signal stack to s. 782 //go:nosplit 783 func signalstack(s *stack) { 784 st := stackt{ss_size: s.hi - s.lo} 785 setSignalstackSP(&st, s.lo) 786 sigaltstack(&st, nil) 787 } 788 789 // setsigsegv is used on darwin/arm{,64} to fake a segmentation fault. 790 //go:nosplit 791 func setsigsegv(pc uintptr) { 792 g := getg() 793 g.sig = _SIGSEGV 794 g.sigpc = pc 795 g.sigcode0 = _SEGV_MAPERR 796 g.sigcode1 = 0 // TODO: emulate si_addr 797 }