Skip to content

os: go1.24rc2 File.copyFile blocks forever in some cases #71459

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

Closed
r-hang opened this issue Jan 27, 2025 · 3 comments
Closed

os: go1.24rc2 File.copyFile blocks forever in some cases #71459

r-hang opened this issue Jan 27, 2025 · 3 comments
Labels
BugReport Issues describing a possible bug in the Go implementation.

Comments

@r-hang
Copy link

r-hang commented Jan 27, 2025

Go version

go1.24rc2

Output of go env in your module/workspace:

go env
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE='on'
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN='/home/user/gocode/bin'
GOCACHE='/home/user/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/user/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build276472280=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/user/gocode/src/code.uber.internal/go.mod'
GOMODCACHE='/home/user/gocode/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/user/gocode'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/user/gocode/src/github.com/golang/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/user/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/user/gocode/src/github.com/golang/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24rc2'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

go1.24rc2 seems to cause some terminal prompt testing programs to block forever. These programs previously ran fine on go1.23.5.
git bisect points to https://go-review.googlesource.com/c/go/+/603295. Specifically, the added syscall logic written, err, handled = poll.SendFile(&f.pfd, int(fd), remain) isn't returning.

I ran the go program provided below in go1.23.5 and it runs to completion with the expected result.

$ GO111MODULE=on /home/user/src/go/bin/go version
go version go1.23.5 linux/amd64

$ GO111MODULE=on /home/user/src/go/bin/go run .                                       
0xc000142780 0xc000142660 9223372036854775807
(0x0,0x0)
pass:  true , error:  <nil>

In go1.24rc2 this program blocks forever

$ GO111MODULE=on /home/user/gocode/src/github.com/golang/go/bin/go version
go version go1.24rc2 linux/amd64

$ GO111MODULE=on /home/user/gocode/src/github.com/golang/go/bin/go run .   
0xc0001b86c0 0xc0001b85a0 9223372036854775807
(0x0,0x0)
Standalone Reproducing Go Program
package main

import (
        "fmt"
        "os"

        expect "github.com/Netflix/go-expect"
        "github.com/creack/pty"
        "github.com/hinshun/vt10x"
        survey "github.com/AlecAivazis/survey/v2"
)

const (
        _prompt = "Name of the user"
        _response = "gopher"
)

// A program to test the interactive prompts of our cli tools.
func main() {
        tty := setupTTY()
        var res string
        err := survey.AskOne(&survey.Input{Message: _prompt}, &res, survey.WithStdio(tty, tty, tty))
        fmt.Println("pass: ", res == _response, ", error: ", err)
}

func setupTTY() *os.File {
        ptm, pts, err := pty.Open()
        if err != nil {
                panic(err)
        }

        term := vt10x.New(vt10x.WithWriter(pts))
        console, err := expect.NewConsole(
                        expect.WithStdin(ptm),
                        expect.WithStdout(term),
                        expect.WithCloser(pts, ptm),
        )
        if err != nil {
                panic(err)
        }

        go func() {
                // console.ExpectString blocks forever on go1.24rc2
                // git bisect points to https://go-review.googlesource.com/c/go/+/603295
                // Specifically, the syscall never returns.
                // ```written, err, handled = poll.SendFile(&f.pfd, int(fd), remain)```
                // never returns.
                _, err := console.ExpectString(_prompt)
                if err != nil {
                        panic(err)
                }
                _, err = console.SendLine(_response)
                if err != nil {
                        panic(err)
                }
                _, err = console.ExpectEOF()
                if err != nil {
                        panic(err)
                }
        }()

        return console.Tty()
}

PS: I tried creating a Go Playground but ran into timeouts.

What did you see happen?

On go1.24rc2 the program blocked.

What did you expect to see?

I expected the program to terminate with the expected result printed.

@seankhliao
Copy link
Member

Reverting CL 603295 is now tracked in #71375

@gabyhelp gabyhelp added the BugReport Issues describing a possible bug in the Go implementation. label Jan 27, 2025
@kolyshkin
Copy link
Contributor

It's the same under the hood as the reproducer in #71735, with io.Copy from a terminal to a pipe. Can be closed as duplicate I guess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BugReport Issues describing a possible bug in the Go implementation.
Projects
None yet
Development

No branches or pull requests

4 participants