Skip to content

testing/synctest: time.Timer.Reset(0) hangs #76052

@mcdoker18

Description

@mcdoker18

Go version

go version go1.25.3 X:nodwarf5 linux/amd64

Output of go env in your module/workspace:

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=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/mcdoker18/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/mcdoker18/.config/go/env'
GOEXE=''
GOEXPERIMENT='nodwarf5'
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2222325429=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/mcdoker18/pet/tgo/go.mod'
GOMODCACHE='/home/mcdoker18/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/mcdoker18/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/mcdoker18/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.3 X:nodwarf5'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Run the following synctest test.

package tgo_test

import (
	"context"
	"testing"
	"testing/synctest"
	"time"
)

func TestTimerSynctest(t *testing.T) {
	synctest.Test(t, func(t *testing.T) {
		timer := time.NewTimer(0)
		timer.Stop() // comment this line to fix

		ctx, cancel := context.WithCancel(t.Context())

		go func() {
			for {
				select {
				case <-ctx.Done():
					return
				case <-timer.C:
				}
			}
		}()

		synctest.Wait()
		timer.Reset(0) // or change the duration to 1
		synctest.Wait()
		cancel()
		synctest.Wait()
	})
}

I also noticed that if you comment out the Timer.Stop or replace the duration value with 1 in the Timer.Reset, the test completes successfully.

What did you see happen?

The test hangs on time.Reset

time.(*Timer).Reset(0xc0000e6150, 0xc0000ea140?)
        /usr/lib/go/src/time/sleep.go:176 +0x34 fp=0xc000089ef8 sp=0xc000089ed0 pc=0x4928d4
tgo_test.TestTimerSynctest.func1(0xc0000fa000)
        /home/mcdoker18/pet/tgo/my_test.go:28 +0xd7 fp=0xc000089f70 sp=0xc000089ef8 pc=0x52b917

Full goroutines dump:

=== RUN   TestTimerSynctest
SIGQUIT: quit
PC=0x482141 m=0 sigcode=0

goroutine 0 gp=0x6c0720 m=0 mp=0x6c1660 [idle, synctest bubble 1]:
runtime.futex(0x6c1b90, 0x80, 0xffffffff, 0x0, 0x0, 0x0)
        /usr/lib/go/src/runtime/sys_linux_amd64.s:557 +0x21 fp=0x7ffe8834ed30 sp=0x7ffe8834ed28 pc=0x482141
runtime.futexsleep(0x445f17?, 0xfa1c0?, 0x100000004?)
        /usr/lib/go/src/runtime/os_linux.go:76 +0x30 fp=0x7ffe8834ed80 sp=0x7ffe8834ed30 pc=0x43d9d0
runtime.semasleep(0xffffffffffffffff)
        /usr/lib/go/src/runtime/lock_futex.go:146 +0x4d fp=0x7ffe8834edb0 sp=0x7ffe8834ed80 pc=0x41566d
runtime.lock2(0xc0000e61b0)
        /usr/lib/go/src/runtime/lock_spinbit.go:250 +0x30e fp=0x7ffe8834ee10 sp=0x7ffe8834edb0 pc=0x415ace
runtime.lockWithRank(...)
        /usr/lib/go/src/runtime/lockrank_off.go:24
runtime.lock(...)
        /usr/lib/go/src/runtime/lock_spinbit.go:152
runtime.(*timer).unlockAndRun(0x6c1660?, 0xc0000f8000?, 0xc0000f8000)
        /usr/lib/go/src/runtime/time.go:1224 +0x225 fp=0x7ffe8834ee90 sp=0x7ffe8834ee10 pc=0x464265
runtime.(*timer).modify.func1()
        /usr/lib/go/src/runtime/time.go:639 +0x1f fp=0x7ffe8834eeb8 sp=0x7ffe8834ee90 pc=0x46341f
runtime.systemstack(0x482a9f)
        /usr/lib/go/src/runtime/asm_amd64.s:513 +0x4a fp=0x7ffe8834eec8 sp=0x7ffe8834eeb8 pc=0x47e4ca

goroutine 9 gp=0xc0000fa1c0 m=0 mp=0x6c1660 [running (durable), synctest bubble 1]:
runtime.systemstack_switch()
        /usr/lib/go/src/runtime/asm_amd64.s:478 +0x8 fp=0xc000089e40 sp=0xc000089e30 pc=0x47e468
runtime.(*timer).modify(0xc0000e6160, 0xd234ccf52430000, 0x0, 0x0, {0x0, 0x0}, 0x0)
        /usr/lib/go/src/runtime/time.go:638 +0x219 fp=0xc000089e88 sp=0xc000089e40 pc=0x463239
runtime.(*timer).reset(...)
        /usr/lib/go/src/runtime/time.go:760
time.resetTimer(0xc0000aa180?, 0xc0000fa1c0?, 0xc0000fa1c0?)
        /usr/lib/go/src/runtime/time.go:435 +0x65 fp=0xc000089ed0 sp=0xc000089e88 pc=0x47c805
time.(*Timer).Reset(0xc0000e6150, 0xc0000ea140?)
        /usr/lib/go/src/time/sleep.go:176 +0x34 fp=0xc000089ef8 sp=0xc000089ed0 pc=0x4928d4
tgo_test.TestTimerSynctest.func1(0xc0000fa000)
        /home/mcdoker18/pet/tgo/my_test.go:28 +0xd7 fp=0xc000089f70 sp=0xc000089ef8 pc=0x52b917
testing.tRunner(0xc0000fa000, 0x58e380)
        /usr/lib/go/src/testing/testing.go:1934 +0xea fp=0xc000089fc0 sp=0xc000089f70 pc=0x4e5cca
testing.testingSynctestTest.gowrap1()
        /usr/lib/go/src/testing/testing.go:2046 +0x25 fp=0xc000089fe0 sp=0xc000089fc0 pc=0x4e6e85
runtime.goexit({})
        /usr/lib/go/src/runtime/asm_amd64.s:1693 +0x1 fp=0xc000089fe8 sp=0xc000089fe0 pc=0x480301
created by testing/synctest.testingSynctestTest in goroutine 8
        /usr/lib/go/src/testing/testing.go:2046 +0x26d

goroutine 1 gp=0xc000002380 m=nil [chan receive]:
runtime.gopark(0x30000005bc8f8?, 0x3004b02263170?, 0x70?, 0x31?, 0x7f4b0225a108?)
        /usr/lib/go/src/runtime/proc.go:460 +0xce fp=0xc0000bc998 sp=0xc0000bc978 pc=0x47898e
runtime.chanrecv(0xc0000a8280, 0xc0000bca7f, 0x1)
        /usr/lib/go/src/runtime/chan.go:667 +0x473 fp=0xc0000bca10 sp=0xc0000bc998 pc=0x410193
runtime.chanrecv1(0x6c01c0?, 0x5bf8c0?)
        /usr/lib/go/src/runtime/chan.go:509 +0x12 fp=0xc0000bca38 sp=0xc0000bca10 pc=0x40fd12
testing.(*T).Run(0xc000003880, {0x5832ac?, 0xc0000bcb30?}, 0x58e2a0)
        /usr/lib/go/src/testing/testing.go:2005 +0x485 fp=0xc0000bcb10 sp=0xc0000bca38 pc=0x4e6ca5
testing.runTests.func1(0xc000003880)
        /usr/lib/go/src/testing/testing.go:2477 +0x37 fp=0xc0000bcb50 sp=0xc0000bcb10 pc=0x4e9017
testing.tRunner(0xc000003880, 0xc0000bcc70)
        /usr/lib/go/src/testing/testing.go:1934 +0xea fp=0xc0000bcba0 sp=0xc0000bcb50 pc=0x4e5cca
testing.runTests(0xc000010060, {0x6b5de0, 0x1, 0x1}, {0x7?, 0xc000014940?, 0x6c0380?})
        /usr/lib/go/src/testing/testing.go:2475 +0x4b4 fp=0xc0000bcca0 sp=0xc0000bcba0 pc=0x4e8ef4
testing.(*M).Run(0xc0000c01e0)
        /usr/lib/go/src/testing/testing.go:2337 +0x63a fp=0xc0000bced0 sp=0xc0000bcca0 pc=0x4e789a
main.main()
        _testmain.go:45 +0x9b fp=0xc0000bcf50 sp=0xc0000bced0 pc=0x52bb5b
runtime.main()
        /usr/lib/go/src/runtime/proc.go:285 +0x29d fp=0xc0000bcfe0 sp=0xc0000bcf50 pc=0x4442fd
runtime.goexit({})
        /usr/lib/go/src/runtime/asm_amd64.s:1693 +0x1 fp=0xc0000bcfe8 sp=0xc0000bcfe0 pc=0x480301

goroutine 2 gp=0xc0000028c0 m=nil [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/lib/go/src/runtime/proc.go:460 +0xce fp=0xc000086fa8 sp=0xc000086f88 pc=0x47898e
runtime.goparkunlock(...)
        /usr/lib/go/src/runtime/proc.go:466
runtime.forcegchelper()
        /usr/lib/go/src/runtime/proc.go:373 +0xb3 fp=0xc000086fe0 sp=0xc000086fa8 pc=0x444633
runtime.goexit({})
        /usr/lib/go/src/runtime/asm_amd64.s:1693 +0x1 fp=0xc000086fe8 sp=0xc000086fe0 pc=0x480301
created by runtime.init.7 in goroutine 1
        /usr/lib/go/src/runtime/proc.go:361 +0x1a

goroutine 3 gp=0xc000002e00 m=nil [GC sweep wait]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/lib/go/src/runtime/proc.go:460 +0xce fp=0xc000087780 sp=0xc000087760 pc=0x47898e
runtime.goparkunlock(...)
        /usr/lib/go/src/runtime/proc.go:466
runtime.bgsweep(0xc0000a8000)
        /usr/lib/go/src/runtime/mgcsweep.go:279 +0x94 fp=0xc0000877c8 sp=0xc000087780 pc=0x42c7b4
runtime.gcenable.gowrap1()
        /usr/lib/go/src/runtime/mgc.go:212 +0x25 fp=0xc0000877e0 sp=0xc0000877c8 pc=0x420805
runtime.goexit({})
        /usr/lib/go/src/runtime/asm_amd64.s:1693 +0x1 fp=0xc0000877e8 sp=0xc0000877e0 pc=0x480301
created by runtime.gcenable in goroutine 1
        /usr/lib/go/src/runtime/mgc.go:212 +0x66

goroutine 4 gp=0xc000002fc0 m=nil [GC scavenge wait]:
runtime.gopark(0xc0000a8000?, 0x5bab10?, 0x1?, 0x0?, 0xc000002fc0?)
        /usr/lib/go/src/runtime/proc.go:460 +0xce fp=0xc000087f78 sp=0xc000087f58 pc=0x47898e
runtime.goparkunlock(...)
        /usr/lib/go/src/runtime/proc.go:466
runtime.(*scavengerState).park(0x6c0400)
        /usr/lib/go/src/runtime/mgcscavenge.go:425 +0x49 fp=0xc000087fa8 sp=0xc000087f78 pc=0x42a289
runtime.bgscavenge(0xc0000a8000)
        /usr/lib/go/src/runtime/mgcscavenge.go:653 +0x3c fp=0xc000087fc8 sp=0xc000087fa8 pc=0x42a81c
runtime.gcenable.gowrap2()
        /usr/lib/go/src/runtime/mgc.go:213 +0x25 fp=0xc000087fe0 sp=0xc000087fc8 pc=0x4207a5
runtime.goexit({})
        /usr/lib/go/src/runtime/asm_amd64.s:1693 +0x1 fp=0xc000087fe8 sp=0xc000087fe0 pc=0x480301
created by runtime.gcenable in goroutine 1
        /usr/lib/go/src/runtime/mgc.go:213 +0xa5

goroutine 5 gp=0xc000003500 m=nil [GOMAXPROCS updater (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/lib/go/src/runtime/proc.go:460 +0xce fp=0xc000088788 sp=0xc000088768 pc=0x47898e
runtime.goparkunlock(...)
        /usr/lib/go/src/runtime/proc.go:466
runtime.updateMaxProcsGoroutine()
        /usr/lib/go/src/runtime/proc.go:6720 +0xe7 fp=0xc0000887e0 sp=0xc000088788 pc=0x452587
runtime.goexit({})
        /usr/lib/go/src/runtime/asm_amd64.s:1693 +0x1 fp=0xc0000887e8 sp=0xc0000887e0 pc=0x480301
created by runtime.defaultGOMAXPROCSUpdateEnable in goroutine 1
        /usr/lib/go/src/runtime/proc.go:6708 +0x37

goroutine 6 gp=0xc0000036c0 m=nil [finalizer wait]:
runtime.gopark(0x453555?, 0x42977c?, 0xe0?, 0x13?, 0x490013?)
        /usr/lib/go/src/runtime/proc.go:460 +0xce fp=0xc000086620 sp=0xc000086600 pc=0x47898e
runtime.runFinalizers()
        /usr/lib/go/src/runtime/mfinal.go:210 +0x107 fp=0xc0000867e0 sp=0xc000086620 pc=0x41f7a7
runtime.goexit({})
        /usr/lib/go/src/runtime/asm_amd64.s:1693 +0x1 fp=0xc0000867e8 sp=0xc0000867e0 pc=0x480301
created by runtime.createfing in goroutine 1
        /usr/lib/go/src/runtime/mfinal.go:172 +0x3d

goroutine 7 gp=0xc000003c00 m=nil [synctest.Run (durable), synctest bubble 1]:
runtime.gopark(0xc000088ed0?, 0x4e5c0d?, 0xc8?, 0xfb?, 0x5dcb73?)
        /usr/lib/go/src/runtime/proc.go:460 +0xce fp=0xc000088e68 sp=0xc000088e48 pc=0x47898e
internal/synctest.Run(0xc0000aa160)
        /usr/lib/go/src/runtime/synctest.go:218 +0x1e6 fp=0xc000088f28 sp=0xc000088e68 pc=0x47c0e6
testing/synctest.Test(0xc000003a40, 0x58e380)
        /usr/lib/go/src/testing/synctest/synctest.go:282 +0x90 fp=0xc000088f50 sp=0xc000088f28 pc=0x52b770
tgo_test.TestTimerSynctest(0xc000003a40?)
        /home/mcdoker18/pet/tgo/my_test.go:11 +0x1a fp=0xc000088f70 sp=0xc000088f50 pc=0x52b81a
testing.tRunner(0xc000003a40, 0x58e2a0)
        /usr/lib/go/src/testing/testing.go:1934 +0xea fp=0xc000088fc0 sp=0xc000088f70 pc=0x4e5cca
testing.(*T).Run.gowrap1()
        /usr/lib/go/src/testing/testing.go:1997 +0x25 fp=0xc000088fe0 sp=0xc000088fc0 pc=0x4e6e25
runtime.goexit({})
        /usr/lib/go/src/runtime/asm_amd64.s:1693 +0x1 fp=0xc000088fe8 sp=0xc000088fe0 pc=0x480301
created by testing.(*T).Run in goroutine 1
        /usr/lib/go/src/testing/testing.go:1997 +0x465

goroutine 8 gp=0xc000003dc0 m=nil [chan receive (durable), synctest bubble 1]:
runtime.gopark(0x7f4b0225a108?, 0x3000000000080?, 0x70?, 0x31?, 0x7f4b0225a108?)
        /usr/lib/go/src/runtime/proc.go:460 +0xce fp=0xc0000896a0 sp=0xc000089680 pc=0x47898e
runtime.chanrecv(0xc0000a8300, 0xc000089767, 0x1)
        /usr/lib/go/src/runtime/chan.go:667 +0x473 fp=0xc000089718 sp=0xc0000896a0 pc=0x410193
runtime.chanrecv1(0x5bd218?, 0x1?)
        /usr/lib/go/src/runtime/chan.go:509 +0x12 fp=0xc000089740 sp=0xc000089718 pc=0x40fd12
testing/synctest.testingSynctestTest(0xc000003a40, 0x58e380)
        /usr/lib/go/src/testing/testing.go:2047 +0x288 fp=0xc0000897b8 sp=0xc000089740 pc=0x4eab68
testing/synctest.Test.func1()
        /usr/lib/go/src/testing/synctest/synctest.go:283 +0x25 fp=0xc0000897e0 sp=0xc0000897b8 pc=0x52b7e5
runtime.goexit({})
        /usr/lib/go/src/runtime/asm_amd64.s:1693 +0x1 fp=0xc0000897e8 sp=0xc0000897e0 pc=0x480301
created by testing/synctest.Test in goroutine 7
        /usr/lib/go/src/testing/synctest/synctest.go:282 +0x90

goroutine 10 gp=0xc0000fa380 m=nil [select (durable), synctest bubble 1]:
runtime.gopark(0xc0000827b0?, 0x2?, 0x0?, 0x0?, 0xc000082794?)
        /usr/lib/go/src/runtime/proc.go:460 +0xce fp=0xc000082620 sp=0xc000082600 pc=0x47898e
runtime.selectgo(0xc0000827b0, 0xc000082790, 0x0?, 0x0, 0x0?, 0x1)
        /usr/lib/go/src/runtime/select.go:351 +0x8b7 fp=0xc000082760 sp=0xc000082620 pc=0x457197
tgo_test.TestTimerSynctest.func1.1()
        /home/mcdoker18/pet/tgo/my_test.go:19 +0x77 fp=0xc0000827e0 sp=0xc000082760 pc=0x52ba37
runtime.goexit({})
        /usr/lib/go/src/runtime/asm_amd64.s:1693 +0x1 fp=0xc0000827e8 sp=0xc0000827e0 pc=0x480301
created by tgo_test.TestTimerSynctest.func1 in goroutine 9
        /home/mcdoker18/pet/tgo/my_test.go:17 +0xc5

rax    0xca
rbx    0xffffffff
rcx    0x482143
rdx    0xffffffff
rdi    0x6c1b90
rsi    0x80
rbp    0x7ffe8834ed70
rsp    0x7ffe8834ed28
r8     0x0
r9     0x0
r10    0x0
r11    0x286
r12    0x1
r13    0xc0000e6001
r14    0x6c0720
r15    0xffffffffffffffff
rip    0x482141
rflags 0x286
cs     0x33
fs     0x0
gs     0x0
exit status 2
FAIL    tgo     11.493s

What did you expect to see?

The test is completed successfully.

Metadata

Metadata

Assignees

Labels

BugReportIssues describing a possible bug in the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions