-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
os: EINTR on darwin from os.Process.Wait #36644
Comments
Perhaps we do have to change the os package for this, but I'd like to clearly understand the root cause first. We have not historically tried to handle all possible |
I did a little investigating. I was unable to replicate this running a normal binary, but it happens reliably when run under lldb:
This is the typical way xcode runs development binaries, which is why we see it so frequently. |
What happens with gdb? |
(It is surprisingly hard to install gdb on macOS 10.15 with codesigning.) Results are similar:
|
Thanks. When I look at that gdb output the first thing that strikes me is: what signal is it? gdb normally reports every signal that a program receives (I don't know about lldb). Why is that not being reported here? When you run |
Not printed, according to I tried setting
(The debugger freezes on run if I attempt to set all signals to print.) |
Thanks. So it sounds like something is installing a I'm trying to drill down on this because if that is what is happening, and we can't avoid it, then we need to add an |
I only see this behavior under lldb and gdb. Googling around, here is a reference claiming that gdb installs a SIGCHLD handler on macOS: https://jmmv.dev/2008/10/boostprocess-and-sigchld.html (I notice Julio Merino is a Google employee, maybe jmmv@ will know more?) Grepping through the GDB sources I don't see any macos-specific code for this, but I am not familiar with the codebase. |
I wonder if this is a side effect of using What happens if your Go c-archive does os.Notify(make(chan syscall.Signal, 1), syscall.SIGCHLD) ? |
Calling |
At least there is a workaround. I don't know what else we can do short of adding |
That is #20400. There, you said (#20400 (comment)):
|
The change can be simultaneously the only realistic approach and yet be undesirable. |
Change https://golang.org/cl/232862 mentions this issue: |
I posted a 1.14 backport request for this: #39026 |
Historically we've assumed that we can install all signal handlers with the SA_RESTART flag set, and let the system restart slow functions if a signal is received. Therefore, we don't have to worry about EINTR. This is only partially true, and we've added EINTR checks already for connect, and open/read on Darwin, and sendfile on Solaris. Other cases have turned up in golang#36644, golang#38033, and golang#38836. Also, golang#20400 points out that when Go code is included in a C program, the C program may install its own signal handlers without SA_RESTART. In that case, Go code will see EINTR no matter what it does. So, go ahead and check for EINTR. We don't check in the syscall package; people using syscalls directly may want to check for EINTR themselves. But we do check for EINTR in the higher level APIs in os and net, and retry the system call if we see it. This change looks safe, but of course we may be missing some cases where we need to check for EINTR. As such cases turn up, we can add tests to runtime/testdata/testprogcgo/eintr.go, and fix the code. If there are any such cases, their handling after this change will be no worse than it is today. For golang#22838 Fixes golang#20400 Fixes golang#36644 Fixes golang#38033 Fixes golang#38836 Change-Id: I7e46ca8cafed0429c7a2386cc9edc9d9d47a6896 Reviewed-on: https://go-review.googlesource.com/c/go/+/232862 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com> (cherry picked from commit 8c1db77)
Background: our Go code is built with
-buildmode=c-archive
and linked into a macOS app built by xcode. We are not installing any signal handlers, but it is possible some Apple library is doing so behind our backs. We are using theos/exec
package to periodically executenetstat -an
.Occasionally, the
os/exec.Cmd.Wait
method is returningEINTR
. ThisEINTR
comes directly from os.Process.Wait. Unfortunately the os/exec package does not expect EINTR, and so it treats it as if the fork process has exited and cleans up its state, so that Cmd.Wait cannot be called again.The darwin man pages
wait(2)
andsigaction(2)
suggest this should only happen if a signal handler does not have the SA_RESTART flag set. I have not yet determined if Apple is setting another handler for us, or if this is something unusual like Issue #11180.Even if this is a core Apple library setting a handler (we use no third-party code), it may be worth handling EINTR for darwin in
os.Process.Wait
, to make the object useful in Go code linked with-buildmode=c-archive
.The text was updated successfully, but these errors were encountered: