https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86331

--- Comment #7 from Ian Lance Taylor <ian at airs dot com> ---
To be clear, the problem is not that the go tool is failing to find its
subcommands.  The problem is that the go tool thinks that the waitid system
call is returning an error.  However, the strace shows that waitid is not
returning an error.

The code calls waitid via syscall.Syscall6 (libgo/go/os/wait_waitid.go).  The
Syscall6 function (libgo/go/syscall/syscall_unix.go) sets errno to 0, calls the
C library syscall function, and then reads errno.  If the errno value that it
reads is not 0, the program will think that the system call to waitid has
failed.  At this point my best guess is that in some cases errno is being set
to ENOENT somehow.  As far as I know this approach of setting errno to 0 and
checking it after the syscall is the only general way to tell whether a syscall
has failed.

I wonder if the fact that this is running in a VM could have something to do
with this.  Perhaps something the VM is doing is sometimes causing the errno
value to change.

It's possible that this patch will work around the problem.  Could you try this
to see if it helps?  Thanks.

diff --git a/libgo/go/os/wait_waitid.go b/libgo/go/os/wait_waitid.go
index 5a62b27f..c2a34ff6 100644
--- a/libgo/go/os/wait_waitid.go
+++ b/libgo/go/os/wait_waitid.go
@@ -28,9 +28,12 @@ func (p *Process) blockUntilWaitable() (bool, error) {
        // We don't care about the values it returns.
        var siginfo [16]uint64
        psig := &siginfo[0]
-       _, _, e := syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid),
uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0)
+       r, _, e := syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid),
uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0)
        runtime.KeepAlive(p)
-       if e != 0 {
+       // Check r as well as e because https://gcc.gnu.org/PR86331
+       // suggests that on arm64 systems in a VM checking only e is
+       // unreliable.
+       if r != 0 && e != 0 {
                // waitid has been available since Linux 2.6.9, but
                // reportedly is not available in Ubuntu on Windows.
                // See issue 16610.

Reply via email to