go: sync: Map.Store() crash with fatal error: sync: unlock of unlocked mutex

Hi,

For some reason our service crashes with this unrecoverable error:

 fatal error: sync: unlock of unlocked mutex
goroutine 866557 [running]: 
runtime.throw(0xc0236c, 0x1e)
	/opt/go1.10.3.linux-amd64/src/runtime/panic.go:616 +0x81 fp=0xc44a9d65c0 sp=0xc44a9d65a0 pc=0x42b191 
sync.throw(0xc0236c, 0x1e)
	/opt/go1.10.3.linux-amd64/src/runtime/panic.go:605 +0x35 fp=0xc44a9d65e0 sp=0xc44a9d65c0 pc=0x42b105 
sync.(*Mutex).Unlock(0xc42522c050)
	/opt/go1.10.3.linux-amd64/src/sync/mutex.go:184 +0xc2 fp=0xc44a9d6608 sp=0xc44a9d65e0 pc=0x46c652 
sync.(*Map).Store(0xc42522c050, 0xabd0c0, 0xc4374e15a0, 0xbabe00, 0xc4305738c0) 
	/opt/go1.10.3.linux-amd64/src/sync/map.go:162

we are using sync.Map as intended (filling the map from multiple go routines).

it’s very random, and i can’t force the crash, but it happens many times per day.

Thanks

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 15 (9 by maintainers)

Most upvoted comments

Yes, I think Flush is the issue. If there are outstanding map operations currently in progress on global.StatsManager.items, you can’t do global.StatsManager.items = sync.Map{}. Although technically that doesn’t violate the rule “don’t copy a map before first use” because the map you’re copying hasn’t been used yet. But you’re copying onto an in-use Map, which is also bad. It may be worth adding something to the doc, although it seems pretty obvious that’s unsafe if you think about it long enough. @bcmills

Speaking of which, the race detector should have caught this bug. Have you tried running with the race detector on?