Skip to content
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

runtime: avoid scary crash from concurrent calls to time.Timer.Reset #25686

Closed
eliasnaur opened this issue Jun 1, 2018 · 1 comment

Comments

Projects
None yet
2 participants
@eliasnaur
Copy link
Contributor

commented Jun 1, 2018

What version of Go are you using (go version)?

go version devel +4bb649fba8 Wed May 23 12:26:19 2018 +0000 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

linux/amd64

What did you do?

While debugging #25619 it took me a while to realize that the scary runtime crash

$ go run timer.go 
panic: (runtime.errorString) (0x46adc0,0x4d0dc0)
fatal error: panic holding locks

goroutine 20 [running]:
runtime.throw(0x47cb63, 0x13)
	/home/elias/dev/go-tip/src/runtime/panic.go:589 +0x6a fp=0xc000045e20 sp=0xc000045df0 pc=0x422f2a
panic(0x46adc0, 0x4d0dc0)
	/home/elias/dev/go-tip/src/runtime/panic.go:454 +0x3ab fp=0xc000045eb0 sp=0xc000045e20 pc=0x422c5b
runtime.panicindex()
	/home/elias/dev/go-tip/src/runtime/panic.go:28 +0x5e fp=0xc000045ed0 sp=0xc000045eb0 pc=0x4219be
runtime.siftupTimer(0xc0000ac000, 0x3, 0x4, 0x5)
	/home/elias/dev/go-tip/src/runtime/time.go:331 +0xe9 fp=0xc000045ee0 sp=0xc000045ed0 pc=0x43c929
runtime.(*timersBucket).addtimerLocked(0x4d63e0, 0xc000096008)
	/home/elias/dev/go-tip/src/runtime/time.go:146 +0xa6 fp=0xc000045f30 sp=0xc000045ee0 pc=0x43c0e6
runtime.addtimer(0xc000096008)
	/home/elias/dev/go-tip/src/runtime/time.go:131 +0x83 fp=0xc000045f60 sp=0xc000045f30 pc=0x43c013
time.startTimer(0xc000096008)
	/home/elias/dev/go-tip/src/runtime/time.go:111 +0x2b fp=0xc000045f78 sp=0xc000045f60 pc=0x43bf2b
time.(*Timer).Reset(0xc000096000, 0x1476b081e8000, 0x1)
	/home/elias/dev/go-tip/src/time/sleep.go:130 +0x81 fp=0xc000045fb0 sp=0xc000045f78 pc=0x455ed1
main.main.func1(0xc000096000)
	/home/elias/snot/timer.go:10 +0x3a fp=0xc000045fd8 sp=0xc000045fb0 pc=0x45ab1a
runtime.goexit()
	/home/elias/dev/go-tip/src/runtime/asm_amd64.s:1365 +0x1 fp=0xc000045fe0 sp=0xc000045fd8 pc=0x44a5b1
created by main.main
	/home/elias/snot/timer.go:8 +0x60

could be caused by simple misuse of time.Timer.Reset. The above crash was easily reproduced with the (incorrect) program

package main

import "time"

func main() {
    t := time.NewTimer(100 * time.Hour)
    for i := 0; i < 8; i++ {
        go func() {
            for {
                t.Reset(100 * time.Hour)
            }
        }()
    }
    select {}
}

What did you expect to see?

The detection of the concurrent use of time.Timer and a friendly crash, the same way concurrent accesses to map (sometimes) fail with a friendly error instead of corrupting memory.

What did you see instead?

A runtime crash "fatal error: panic holding locks", which lead me to believe that the Go runtime was at fault.

@gopherbot

This comment has been minimized.

Copy link

commented Jun 1, 2018

Change https://golang.org/cl/115815 mentions this issue: runtime: don't crash holding locks on racy timer access

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.