go runtime_error ai_generated true

fatal error: 所有 goroutine 都休眠 - 死锁! (sync.Once.Do 递归)

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

ID: go/sync-once-reentrant

其他格式: JSON · Markdown 中文 · English
80%修复率
84%置信度
0证据数
2024-11-21首次发现

版本兼容性

版本状态引入弃用备注
1.18 active — — —
1.20 active — — —
1.22 active — — —

根因分析

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

English

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

解决方案

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

无效尝试

常见但无效的做法:

  1. 90% 失败

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

  2. 70% 失败

    Reintroduces the data race Once was meant to prevent.