Skip to content

Commit f770366

Browse files
runtime: don't treat SIGURG as a bad signal
It's possible for the scheduler to try to preempt a goroutine running on a thread created by C code just as the goroutine returns from Go code to C code. If that happens, the goroutine will have a nil g, which would normally cause us to enter the badsignal code. The badsignal code will allocate an M, reset the signal handler, and raise the signal. This is all wasted work for SIGURG, as the default behavior is for the kernel to ignore the signal. It also means that there is a period of time when preemption requests are ignored, because the signal handler is reset to the default. And, finally, it triggers a bug on 386 OpenBSD 6.2. So stop doing it. No test because there is no real change in behavior (other than on OpenBSD), the new code is just more efficient Fixes #36996 Change-Id: I8c1cb9bc09f5ef890cab567924417e2423fc71f6 Reviewed-on: https://go-review.googlesource.com/c/go/+/217617 Reviewed-by: Austin Clements <[email protected]>
1 parent e3f2e9a commit f770366

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

src/runtime/signal_unix.go

+10
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,16 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
412412
sigprofNonGoPC(c.sigpc())
413413
return
414414
}
415+
if sig == sigPreempt && preemptMSupported && debug.asyncpreemptoff == 0 {
416+
// This is probably a signal from preemptM sent
417+
// while executing Go code but received while
418+
// executing non-Go code.
419+
// We got past sigfwdgo, so we know that there is
420+
// no non-Go signal handler for sigPreempt.
421+
// The default behavior for sigPreempt is to ignore
422+
// the signal, so badsignal will be a no-op anyway.
423+
return
424+
}
415425
c.fixsigcode(sig)
416426
badsignal(uintptr(sig), c)
417427
return

0 commit comments

Comments
 (0)