Waitgroup Add In Goroutine
ID |
go.waitgroup_add_in_goroutine |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Go |
Tags |
concurrency, reliability |
Description
Reports a wg.Add(…) call placed inside the body of a goroutine started with
go func() { … }(). A sync.WaitGroup must be told about a goroutine before that goroutine
is launched.
Rationale
When Add runs inside the goroutine, the launching side may reach wg.Wait() before the
goroutine has had a chance to run Add. Wait then sees a counter of zero, returns
immediately, and the program proceeds as if the work were finished — a data race that fails
intermittently and is hard to reproduce. Calling Add before the go statement guarantees
the counter is non-zero by the time Wait is reached.
go func() {
wg.Add(1) // FLAW — Add runs inside the goroutine
defer wg.Done()
}()
wg.Add(1) // OK — Add before launching the goroutine
go func() {
defer wg.Done()
}()
Remediation
Move the wg.Add(…) call out of the goroutine body so it executes before the go
statement that launches the goroutine.