go
runtime_error
ai_generated
true
panic: sync: WaitGroup 计数器为负数
panic: sync: negative WaitGroup counter
ID: go/sync-waitgroup-negative-counter
80%修复率
89%置信度
0证据数
2024-02-14首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 1.x | active | — | — | — |
根因分析
wg.Done() 调用次数大于 wg.Add(n),常见于在未 Add 的 goroutine 中调用 Done,或 Wait 返回后才调用 Add。
English
wg.Done() is called more times than wg.Add(n), often because Done is called in a goroutine that was never added, or Add is called after Wait has already returned.
解决方案
-
97% 成功率
for _, item := range items { wg.Add(1) go func(it Item) { defer wg.Done() process(it) }(item) } wg.Wait() -
95% 成功率
g, ctx := errgroup.WithContext(ctx) for _, it := range items { it := it g.Go(func() error { return process(ctx, it) }) } if err := g.Wait(); err != nil { return err }
无效尝试
常见但无效的做法:
-
70% 失败
Race with wg.Wait(): Wait may return before Add runs, then Done panics or Wait returns early.
-
75% 失败
Hides the bug; the WaitGroup is now inconsistent and Wait may hang or return prematurely.