go runtime_error ai_generated true

fatal error: all goroutines are asleep - deadlock! (sync.Once.Do recursion)

ID: go/sync-once-reentrant

Also available as: JSON · Markdown · 中文
80%Fix Rate
84%Confidence
0Evidence
2024-11-21First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1.18 active — — —
1.20 active — — —
1.22 active — — —

Root Cause

A sync.Once.Do function calls Do again on the same Once (directly or indirectly), causing self-deadlock because Once holds an internal mutex while running f.

generic

中文

sync.Once.Do 的函数再次(直接或间接)对同一个 Once 调用 Do,导致自死锁,因为 Once 在执行 f 时持有内部互斥锁。

Workarounds

  1. 95% success
    var once sync.Once
    once.Do(func() {
        // do not reference `once` here
        initConfig()
    })
  2. 88% success
    var onceA, onceB sync.Once
    onceA.Do(initA)
    onceB.Do(initB)

Dead Ends

Common approaches that don't work:

  1. 90% fail

    The deadlock is internal to Once; no timeout can break the held mutex.

  2. 70% fail

    Reintroduces the data race Once was meant to prevent.