go
runtime_error
ai_generated
true
panic: sync: WaitGroup 计数器为负
panic: sync: negative WaitGroup counter
ID: go/negative-waitgroup-counter
80%修复率
90%置信度
0证据数
2024-04-15首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 1.x | active | — | — | — |
根因分析
wg.Done() 调用次数多于 wg.Add(n)。常见于在迭代次数多于 Add 的循环中 defer Done,或有 goroutine 调用 Done 却没有匹配的 Add。
English
wg.Done() is called more times than wg.Add(n). Common when Done is deferred in a loop that runs more iterations than Add, or a goroutine calls Done without a matching Add.
解决方案
-
95% 成功率
Call Add(1) synchronously before launching each goroutine and defer Done inside: for _, item := range items { wg.Add(1) go func(it Item){ defer wg.Done(); process(it) }(item) } wg.Wait() -
92% 成功率
Use golang.org/x/sync/errgroup which manages the counter correctly: g, ctx := errgroup.WithContext(ctx) for _, it := range items { it := it; g.Go(func() error { return process(ctx, it) }) } return g.Wait()
无效尝试
常见但无效的做法:
-
85% 失败
Race: Wait() may return before the goroutine has called Add, causing Done to decrement below zero or the wait to miss the goroutine.
-
80% 失败
The counter is already corrupted; recover leaves the WaitGroup in an invalid state.