type sigTabT … //go:linkname os_sigpipe os.sigpipe func os_sigpipe() { … } func signame(sig uint32) string { … } const _SIG_DFL … const _SIG_IGN … const sigPreempt … var fwdSig … var handlingSig … var disableSigChan … var enableSigChan … var maskUpdatedChan … func init() { … } var signalsOK … // Initialize signals. // Called by libpreinit so runtime may not be initialized. // //go:nosplit //go:nowritebarrierrec func initsig(preinit bool) { … } //go:nosplit //go:nowritebarrierrec func sigInstallGoHandler(sig uint32) bool { … } // sigenable enables the Go signal handler to catch the signal sig. // It is only called while holding the os/signal.handlers lock, // via os/signal.enableSignal and signal_enable. func sigenable(sig uint32) { … } // sigdisable disables the Go signal handler for the signal sig. // It is only called while holding the os/signal.handlers lock, // via os/signal.disableSignal and signal_disable. func sigdisable(sig uint32) { … } // sigignore ignores the signal sig. // It is only called while holding the os/signal.handlers lock, // via os/signal.ignoreSignal and signal_ignore. func sigignore(sig uint32) { … } // clearSignalHandlers clears all signal handlers that are not ignored // back to the default. This is called by the child after a fork, so that // we can enable the signal mask for the exec without worrying about // running a signal handler in the child. // //go:nosplit //go:nowritebarrierrec func clearSignalHandlers() { … } // setProcessCPUProfilerTimer is called when the profiling timer changes. // It is called with prof.signalLock held. hz is the new timer, and is 0 if // profiling is being disabled. Enable or disable the signal as // required for -buildmode=c-archive. func setProcessCPUProfilerTimer(hz int32) { … } // setThreadCPUProfilerHz makes any thread-specific changes required to // implement profiling at a rate of hz. // No changes required on Unix systems when using setitimer. func setThreadCPUProfilerHz(hz int32) { … } func sigpipe() { … } // doSigPreempt handles a preemption signal on gp. func doSigPreempt(gp *g, ctxt *sigctxt) { … } const preemptMSupported … // preemptM sends a preemption request to mp. This request may be // handled asynchronously and may be coalesced with other requests to // the M. When the request is received, if the running G or P are // marked for preemption and the goroutine is at an asynchronous // safe-point, it will preempt the goroutine. It always atomically // increments mp.preemptGen after handling a preemption request. func preemptM(mp *m) { … } // sigFetchG fetches the value of G safely when running in a signal handler. // On some architectures, the g value may be clobbered when running in a VDSO. // See issue #32912. // //go:nosplit func sigFetchG(c *sigctxt) *g { … } // sigtrampgo is called from the signal handler function, sigtramp, // written in assembly code. // This is called by the signal handler, and the world may be stopped. // // It must be nosplit because getg() is still the G that was running // (if any) when the signal was delivered, but it's (usually) called // on the gsignal stack. Until this switches the G to gsignal, the // stack bounds check won't work. // //go:nosplit //go:nowritebarrierrec func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { … } var sigprofCallers … var sigprofCallersUse … // sigprofNonGo is called if we receive a SIGPROF signal on a non-Go thread, // and the signal handler collected a stack trace in sigprofCallers. // When this is called, sigprofCallersUse will be non-zero. // g is nil, and what we can do is very limited. // // It is called from the signal handling functions written in assembly code that // are active for cgo programs, cgoSigtramp and sigprofNonGoWrapper, which have // not verified that the SIGPROF delivery corresponds to the best available // profiling source for this thread. // //go:nosplit //go:nowritebarrierrec func sigprofNonGo(sig uint32, info *siginfo, ctx unsafe.Pointer) { … } // sigprofNonGoPC is called when a profiling signal arrived on a // non-Go thread and we have a single PC value, not a stack trace. // g is nil, and what we can do is very limited. // //go:nosplit //go:nowritebarrierrec func sigprofNonGoPC(pc uintptr) { … } // adjustSignalStack adjusts the current stack guard based on the // stack pointer that is actually in use while handling a signal. // We do this in case some non-Go code called sigaltstack. // This reports whether the stack was adjusted, and if so stores the old // signal stack in *gsigstack. // //go:nosplit func adjustSignalStack(sig uint32, mp *m, gsigStack *gsignalStack) bool { … } var crashing … var testSigtrap … var testSigusr1 … var sigsysIgnored … //go:linkname ignoreSIGSYS os.ignoreSIGSYS func ignoreSIGSYS() { … } //go:linkname restoreSIGSYS os.restoreSIGSYS func restoreSIGSYS() { … } // sighandler is invoked when a signal occurs. The global g will be // set to a gsignal goroutine and we will be running on the alternate // signal stack. The parameter gp will be the value of the global g // when the signal occurred. The sig, info, and ctxt parameters are // from the system signal handler: they are the parameters passed when // the SA is passed to the sigaction system call. // // The garbage collector may have stopped the world, so write barriers // are not allowed. // //go:nowritebarrierrec func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) { … } func fatalsignal(sig uint32, c *sigctxt, gp *g, mp *m) *g { … } // sigpanic turns a synchronous signal into a run-time panic. // If the signal handler sees a synchronous panic, it arranges the // stack to look like the function where the signal occurred called // sigpanic, sets the signal's PC value to sigpanic, and returns from // the signal handler. The effect is that the program will act as // though the function that got the signal simply called sigpanic // instead. // // This must NOT be nosplit because the linker doesn't know where // sigpanic calls can be injected. // // The signal handler must not inject a call to sigpanic if // getg().throwsplit, since sigpanic may need to grow the stack. // // This is exported via linkname to assembly in runtime/cgo. // //go:linkname sigpanic func sigpanic() { … } // dieFromSignal kills the program with a signal. // This provides the expected exit status for the shell. // This is only called with fatal signals expected to kill the process. // //go:nosplit //go:nowritebarrierrec func dieFromSignal(sig uint32) { … } // raisebadsignal is called when a signal is received on a non-Go // thread, and the Go program does not want to handle it (that is, the // program has not called os/signal.Notify for the signal). func raisebadsignal(sig uint32, c *sigctxt) { … } //go:nosplit func crash() { … } // ensureSigM starts one global, sleeping thread to make sure at least one thread // is available to catch signals enabled for os/signal. func ensureSigM() { … } // This is called when we receive a signal when there is no signal stack. // This can only happen if non-Go code calls sigaltstack to disable the // signal stack. func noSignalStack(sig uint32) { … } // This is called if we receive a signal when there is a signal stack // but we are not on it. This can only happen if non-Go code called // sigaction without setting the SS_ONSTACK flag. func sigNotOnStack(sig uint32, sp uintptr, mp *m) { … } // signalDuringFork is called if we receive a signal while doing a fork. // We do not want signals at that time, as a signal sent to the process // group may be delivered to the child process, causing confusion. // This should never be called, because we block signals across the fork; // this function is just a safety check. See issue 18600 for background. func signalDuringFork(sig uint32) { … } // This runs on a foreign stack, without an m or a g. No stack split. // //go:nosplit //go:norace //go:nowritebarrierrec func badsignal(sig uintptr, c *sigctxt) { … } //go:noescape func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer) // Determines if the signal should be handled by Go and if not, forwards the // signal to the handler that was installed before Go's. Returns whether the // signal was forwarded. // This is called by the signal handler, and the world may be stopped. // //go:nosplit //go:nowritebarrierrec func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool { … } // sigsave saves the current thread's signal mask into *p. // This is used to preserve the non-Go signal mask when a non-Go // thread calls a Go function. // This is nosplit and nowritebarrierrec because it is called by needm // which may be called on a non-Go thread with no g available. // //go:nosplit //go:nowritebarrierrec func sigsave(p *sigset) { … } // msigrestore sets the current thread's signal mask to sigmask. // This is used to restore the non-Go signal mask when a non-Go thread // calls a Go function. // This is nosplit and nowritebarrierrec because it is called by dropm // after g has been cleared. // //go:nosplit //go:nowritebarrierrec func msigrestore(sigmask sigset) { … } var sigsetAllExiting … // sigblock blocks signals in the current thread's signal mask. // This is used to block signals while setting up and tearing down g // when a non-Go thread calls a Go function. When a thread is exiting // we use the sigsetAllExiting value, otherwise the OS specific // definition of sigset_all is used. // This is nosplit and nowritebarrierrec because it is called by needm // which may be called on a non-Go thread with no g available. // //go:nosplit //go:nowritebarrierrec func sigblock(exiting bool) { … } // unblocksig removes sig from the current thread's signal mask. // This is nosplit and nowritebarrierrec because it is called from // dieFromSignal, which can be called by sigfwdgo while running in the // signal handler, on the signal stack, with no g available. // //go:nosplit //go:nowritebarrierrec func unblocksig(sig uint32) { … } // minitSignals is called when initializing a new m to set the // thread's alternate signal stack and signal mask. func minitSignals() { … } // minitSignalStack is called when initializing a new m to set the // alternate signal stack. If the alternate signal stack is not set // for the thread (the normal case) then set the alternate signal // stack to the gsignal stack. If the alternate signal stack is set // for the thread (the case when a non-Go thread sets the alternate // signal stack and then calls a Go function) then set the gsignal // stack to the alternate signal stack. We also set the alternate // signal stack to the gsignal stack if cgo is not used (regardless // of whether it is already set). Record which choice was made in // newSigstack, so that it can be undone in unminit. func minitSignalStack() { … } // minitSignalMask is called when initializing a new m to set the // thread's signal mask. When this is called all signals have been // blocked for the thread. This starts with m.sigmask, which was set // either from initSigmask for a newly created thread or by calling // sigsave if this is a non-Go thread calling a Go function. It // removes all essential signals from the mask, thus causing those // signals to not be blocked. Then it sets the thread's signal mask. // After this is called the thread can receive signals. func minitSignalMask() { … } // unminitSignals is called from dropm, via unminit, to undo the // effect of calling minit on a non-Go thread. // //go:nosplit func unminitSignals() { … } // blockableSig reports whether sig may be blocked by the signal mask. // We never want to block the signals marked _SigUnblock; // these are the synchronous signals that turn into a Go panic. // We never want to block the preemption signal if it is being used. // In a Go program--not a c-archive/c-shared--we never want to block // the signals marked _SigKill or _SigThrow, as otherwise it's possible // for all running threads to block them and delay their delivery until // we start a new thread. When linked into a C program we let the C code // decide on the disposition of those signals. func blockableSig(sig uint32) bool { … } type gsignalStack … // setGsignalStack sets the gsignal stack of the current m to an // alternate signal stack returned from the sigaltstack system call. // It saves the old values in *old for use by restoreGsignalStack. // This is used when handling a signal if non-Go code has set the // alternate signal stack. // //go:nosplit //go:nowritebarrierrec func setGsignalStack(st *stackt, old *gsignalStack) { … } // restoreGsignalStack restores the gsignal stack to the value it had // before entering the signal handler. // //go:nosplit //go:nowritebarrierrec func restoreGsignalStack(st *gsignalStack) { … } // signalstack sets the current thread's alternate signal stack to s. // //go:nosplit func signalstack(s *stack) { … } // setsigsegv is used on darwin/arm64 to fake a segmentation fault. // // This is exported via linkname to assembly in runtime/cgo. // //go:nosplit //go:linkname setsigsegv func setsigsegv(pc uintptr) { … }