signal: remove SIGURG from default-ignore list - #2744
Conversation
Go 1.14+ uses SIGURG to implement asynchronous goroutine preemption (runtime/signal_unix.go). With SIGURG silently ignored, Go's runtime cannot preempt goroutines cooperatively, leading to a 'fatal: bad g in signal handler' crash on startup. Removing SIGURG from the default-ignore list lets it fall through to the default POSIX disposition (ignored for processes that haven't installed a handler), while allowing Go's runtime_sigInstall to register its own handler correctly.
|
I tested this one hoping to corroborate it, but the measurements point the other way, so passing them along rather than sitting on them. Master already behaves correctly, and this patch changes it to something Linux does not do.
static int signal_action(struct sighand *sighand, int sig) {
if (signal_is_blockable(sig)) {
struct sigaction_ *action = &sighand->action[sig];
if (action->handler == SIG_IGN_)
return SIGNAL_IGNORE;
if (action->handler != SIG_DFL_)
return SIGNAL_CALL_HANDLER; // installed handler wins here
}
switch (sig) {
case SIGURG_: ... return SIGNAL_IGNORE; // only reached for SIG_DFLSo the list only sets the default action. A process that installs a SIGURG handler — which is what the Go runtime does for async preemption — returns at And per Measured with one static i386 binary run three ways — it installs a handler and raises SIGURG, then forks a child that resets to
Master matches Linux exactly on both. With the patch, a default-disposition SIGURG kills the process, which no Linux program expects — and it does not change the installed-handler case at all, which is the one Go depends on. If Go's preemption really is misbehaving under iSH, the cause looks like it is somewhere else — signal delivery to a blocked thread, or restart semantics, rather than the disposition table. Happy to help chase it with the same setup if you have a Go reproducer; I have a real-Intel Linux box wired up for exactly this kind of A/B. |
Problem
SIGURGis currently in iSH's default-ignore list inkernel/signal.c:Go 1.14+ uses
SIGURGto implement asynchronous goroutine preemption (runtime/signal_unix.go). When a Go program callssignal.Notifyor the runtime installs its ownSIGURGhandler viaruntime_sigInstall, iSH's default-ignore classification prevents proper handler registration.The result is a hard crash on startup:
The workaround is to set
GODEBUG=asyncpreemptoff=1before launch, which disables Go's async preemption entirely — a significant runtime regression.Fix
Remove
SIGURG_from the ignore list. Its POSIX default disposition is already "ignored" for processes that haven't installed a handler, so removing it from this list has no effect on programs that don't useSIGURG. It only allows programs like Go to successfully install their own handler.Impact
GODEBUG=asyncpreemptoff=1SIGURG