Repository navigation
os: File.Close hangs with concurrent I/O on Windows using go1.26rc2 #77404
Copy link
Copy link
Closed
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.FixPendingIssues that have a fix which has not yet been reviewed or submitted.Issues that have a fix which has not yet been reviewed or submitted.OS-Windows
Milestone
Description
Go version
go version go1.26rc2 windows/arm64
Output of go env in your module/workspace:
set AR=ar
set CC=gcc
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_ENABLED=1
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set CXX=g++
set GCCGO=gccgo
set GO111MODULE=
set GOARCH=arm64
set GOARM64=v8.0
set GOAUTH=netrc
set GOBIN=
set GOCACHE=C:\Users\qmuntaldiaz\AppData\Local\go-build
set GOCACHEPROG=
set GODEBUG=
set GOENV=C:\Users\qmuntaldiaz\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFIPS140=off
set GOFLAGS=
set GOGCCFLAGS=-mthreads -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\QMUNTA~1\AppData\Local\Temp\go-build712794263=/tmp/go-build -gno-record-gcc-switches
set GOHOSTARCH=arm64
set GOHOSTOS=windows
set GOINSECURE=
set GOMOD=NUL
set GOMODCACHE=C:\Users\qmuntaldiaz\go\pkg\mod
set GONOPROXY=github.com/microsoft
set GONOSUMDB=github.com/microsoft
set GOOS=windows
set GOPATH=C:\Users\qmuntaldiaz\go
set GOPRIVATE=github.com/microsoft
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Users\qmuntaldiaz\sdk\go1.26rc2
set GOSUMDB=sum.golang.org
set GOTELEMETRY=on
set GOTELEMETRYDIR=C:\Users\qmuntaldiaz\AppData\Roaming\go\telemetry
set GOTMPDIR=
set GOTOOLCHAIN=auto
set GOTOOLDIR=C:\Users\qmuntaldiaz\sdk\go1.26rc2\pkg\tool\windows_arm64
set GOVCS=
set GOVERSION=go1.26rc2
set GOWORK=
set PKG_CONFIG=pkg-confiWhat did you do?
Run the following test using go1.26rc2 test -run TestFileIOCloseRace -count 5 -timeout 10s.
func TestFileIOCloseRace(t *testing.T) {
t.Parallel()
file, err := os.Create(filepath.Join(t.TempDir(), "test.txt"))
if err != nil {
t.Fatal(err)
}
var wg sync.WaitGroup
wg.Go(func() {
if err := file.Close(); err != nil {
t.Error(err)
}
})
// Write a lot of data to increase the chance that
// the Write runs concurrently with the Close.
var tmp [1000]byte
if _, err := file.Write(tmp[:]); err != nil && !errors.Is(err, os.ErrClosed) {
t.Fatal(err)
}
wg.Wait()
}What did you see happen?
Test passes. In fact, it does pass using go1.25.
What did you expect to see?
file.Close hangs indefinitely.
panic: test timed out after 10s
running tests:
TestFileIOCloseRace (10s)
goroutine 18 [running]:
testing.(*M).startAlarm.func1()
C:/Users/qmuntaldiaz/code/golang-go/src/testing/testing.go:2802 +0x2c4
created by time.goFunc
C:/Users/qmuntaldiaz/code/golang-go/src/time/sleep.go:215 +0x38
goroutine 1 [chan receive]:
testing.tRunner.func1()
C:/Users/qmuntaldiaz/code/golang-go/src/testing/testing.go:1993 +0x3c4
testing.tRunner(0x6aead2854000, 0x6aead2845be8)
C:/Users/qmuntaldiaz/code/golang-go/src/testing/testing.go:2042 +0xec
testing.runTests({0x0, 0x0}, {0x7ff6a2b98019, 0x2}, 0x6aead2796210, {0x7ff6a2e03840, 0x11c, 0x11c}, {0x6aead2845c78?, 0x7ff6a2a1c760?, ...})
C:/Users/qmuntaldiaz/code/golang-go/src/testing/testing.go:2583 +0x3e8
testing.(*M).Run(0x6aead280c280)
C:/Users/qmuntaldiaz/code/golang-go/src/testing/testing.go:2443 +0x578
os_test.TestMain(0x6aead280c280)
C:/Users/qmuntaldiaz/code/golang-go/src/os/os_test.go:41 +0xac
main.main()
_testmain.go:658 +0x88
goroutine 8 [sync.WaitGroup.Wait]:
sync.runtime_SemacquireWaitGroup(0x3e8?, 0xe8?)
C:/Users/qmuntaldiaz/code/golang-go/src/runtime/sema.go:114 +0x38
sync.(*WaitGroup).Wait(0x6aead2798330)
C:/Users/qmuntaldiaz/code/golang-go/src/sync/waitgroup.go:206 +0xa8
os_test.TestFileIOCloseRace(0x6aead2854200)
C:/Users/qmuntaldiaz/code/golang-go/src/os/os_test.go:3490 +0x170
testing.tRunner(0x6aead2854200, 0x7ff6a2dd75f8)
C:/Users/qmuntaldiaz/code/golang-go/src/testing/testing.go:2036 +0xac
created by testing.(*T).Run in goroutine 1
C:/Users/qmuntaldiaz/code/golang-go/src/testing/testing.go:2101 +0x394
goroutine 9 [semacquire]:
internal/poll.runtime_Semacquire(0x6aead281e300?)
C:/Users/qmuntaldiaz/code/golang-go/src/runtime/sema.go:76 +0x2c
internal/poll.(*FD).Close(0x6aead281e300)
C:/Users/qmuntaldiaz/code/golang-go/src/internal/poll/fd_windows.go:534 +0x78
os.(*file).close(0x6aead281e300)
C:/Users/qmuntaldiaz/code/golang-go/src/os/file_windows.go:178 +0x88
os.(*File).Close(...)
C:/Users/qmuntaldiaz/code/golang-go/src/os/file_posix.go:23
os_test.TestFileIOCloseRace.func1()
C:/Users/qmuntaldiaz/code/golang-go/src/os/os_test.go:3480 +0x3c
sync.(*WaitGroup).Go.func1()
C:/Users/qmuntaldiaz/code/golang-go/src/sync/waitgroup.go:258 +0x48
created by sync.(*WaitGroup).Go in goroutine 8
C:/Users/qmuntaldiaz/code/golang-go/src/sync/waitgroup.go:238 +0x70
FAIL os 10.261s
FAIL
@dmitshur @golang/release
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.FixPendingIssues that have a fix which has not yet been reviewed or submitted.Issues that have a fix which has not yet been reviewed or submitted.OS-Windows
Activity
qmuntal commentedon Feb 2, 2026
This regression was introduced in CL 698096.
qmuntal commentedon Feb 2, 2026
@gopherbot please open a backport issue for Go 1.26.
gopherbot commentedon Feb 2, 2026
Backport issue(s) opened: #77405 (for 1.26).
Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.
gopherbot commentedon Feb 2, 2026
Change https://go.dev/cl/740921 mentions this issue:
internal/poll: readWriteUnlock should destroy fd when no remaining referencesgabyhelp commentedon Feb 2, 2026
Related Issues
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
gopherbot commentedon Feb 3, 2026
Change https://go.dev/cl/741360 mentions this issue:
[release-branch.go1.26] internal/poll: readWriteUnlock should destroy fd when no remaining references[release-branch.go1.26] internal/poll: readWriteUnlock should destroy…
[release-branch.go1.26] internal/poll: readWriteUnlock should destroy…
[release-branch.go1.26] internal/poll: readWriteUnlock should destroy…