Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: A QEMU signaling fix causes Go binaries to fail on startup. #33746

Closed
joshkunz opened this issue Aug 20, 2019 · 13 comments
Closed

runtime: A QEMU signaling fix causes Go binaries to fail on startup. #33746

joshkunz opened this issue Aug 20, 2019 · 13 comments
Assignees
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@joshkunz
Copy link

tl;dr: In anticipation of a future QEMU work-around, Go should hide runtime rt_sigaction failures for SIGRTMAX - 1, like it already does for SIGRTMAX.

QEMU user mode emulation has a bug where it will not correctly deliver the SIGRTMIN + 1 signal. This is because SIGRTMIN + 1 is a glibc reserved signal, and it is caught in the emulator's glibc. To get around this issue there is a patch to map SIGRTMIN + 1 to SIGRTMAX - 1, a signal that is typically unused. QEMU already has a similar work-around, mapping SIGRTMIN to SIGRTMAX which is also a signal reserved by glibc.

On startup, the Go attempts to register signal handlers for all signals, but it silently hides failures for SIGRTMIN, SIGRTMIN + 1 (the glibc reserved signals), and SIGRTMAX (the QEMU mapped signal for SIGRTMIN). If the QEMU patch is submitted, go programs running under QEMU will fail to run, due to panics when trying to register a handler for SIGRTMAX - 1.

If Go decides to preemptively fix this issue, the patch is simple: just ignore failures for signal 63 in addition to 64. I will follow up this issue with a patch shortly.

@joshkunz
Copy link
Author

@dsnet who I mentioned this to previously.

@dsnet
Copy link
Member

dsnet commented Aug 20, 2019

\cc @ianlancetaylor

@bcmills bcmills added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 20, 2019
@bcmills bcmills added this to the Go1.14 milestone Aug 20, 2019
@gopherbot
Copy link
Contributor

Change https://golang.org/cl/191000 mentions this issue: runtime: avoid panicking on sigaction failure for SIGRTMAX-1

@bmkessler
Copy link
Contributor

Is there a more robust way to handle this issue? From the signal(7) manpage http://man7.org/linux/man-pages/man7/signal.7.html:

   Real-time signals
   Starting with version 2.2, Linux supports real-time signals as
   originally defined in the POSIX.1b real-time extensions (and now
   included in POSIX.1-2001).  The range of supported real-time signals
   is defined by the macros SIGRTMIN and SIGRTMAX.  POSIX.1-2001
   requires that an implementation support at least _POSIX_RTSIG_MAX (8)
   real-time signals.

   The Linux kernel supports a range of 33 different real-time signals,
   numbered 32 to 64.  However, the glibc POSIX threads implementation
   internally uses two (for NPTL) or three (for LinuxThreads) real-time
   signals (see pthreads(7)), and adjusts the value of SIGRTMIN suitably
   (to 34 or 35).  Because the range of available real-time signals
   varies according to the glibc threading implementation (and this
   variation can occur at run time according to the available kernel and
   glibc), and indeed the range of real-time signals varies across UNIX
   systems, programs should never refer to real-time signals using hard-
   coded numbers, but instead should always refer to real-time signals
   using the notation SIGRTMIN+n, and include suitable (run-time) checks
   that SIGRTMIN+n does not exceed SIGRTMAX.

Which says values 63 and 64 that qemu ends up using in the common case when SIGRTMAX==64 shouldn't be hardcoded.

I'm bringing it up because currently Go programs compiled for linux/mips (mips mipsle mips64 mips64le) fail on startup running in qemu user mode on most architectures (amd64 etc.) due to a related issue. The go compiler hardcodes that realtime signals go up to 128 on linux/mips (implicitly that SIGRTMAX==128 on linux/mips https://github.com/golang/go/blob/77f9b2728eb08456899e6500328e00ec4829dddf/src/runtime/sigtab_linux_mipsx.go) and on startup sigaction on 65 and above fail on amd64 etc. It would be nice to have a solution general enough to allow mips programs to run under qemu user mode as well.

@ianlancetaylor
Copy link
Member

From further discussion the situation with QEMU is complex. This issue was filed in anticipation of changes that have not yet occurred. So I am putting the issue on hold for now.

@tomkcook
Copy link

tomkcook commented Nov 15, 2019

Unsure if it's related, but I see similar crashes in the go compiler (ie go build) for both go 1.11 and go 1.13 running on any version of qemu (I've tried most releases from 3.0.0 to 4.1.0) when building a "Hello, world" program. I'm using the go binaries from the Alpine Linux repositories.

@ianlancetaylor
Copy link
Member

@tomkcook Can you clarify what you mean by "similar crashes?" Can you show us the output of the crash? Thanks.

@bcmills
Copy link
Contributor

bcmills commented Nov 15, 2019

Note that we currently lack a QEMU builder (#1508), and per http://golang.org/wiki/PortingPolicy, supported platforms require builders.

I don't think we should be putting in QEMU-specific workarounds until/unless we have a builder to test for regressions in those workarounds.

@yuchunyu97

This comment has been minimized.

@joshkunz

This comment has been minimized.

biodrone added a commit to dangeroustech/MPGSMerchantServer that referenced this issue Mar 14, 2020
golang/go#33746 (comment)

Removing ARM and ARM64 builds until a QEMU builder exists
@bradfitz
Copy link
Contributor

bradfitz commented Nov 1, 2021

Not sure when it happened, but I noticed that qemu-user 5.2.0 in Debian Bullseye works with Go binaries!

As one bisect datapoint, qemu 4.2 in Ubuntu Focal doesn't work.

(in this case, I tested Go 1.17 binaries in both cases)

@seankhliao
Copy link
Member

Is this still relevant to recent qemu/go releases?

@ianlancetaylor ianlancetaylor added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jun 25, 2022
@gopherbot
Copy link
Contributor

Timed out in state WaitingForInfo. Closing.

(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)

@golang golang locked and limited conversation to collaborators Jul 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

10 participants