Problem
Our detector reports false positive races when user code uses iter.Pull (Go 1.23+) or other stdlib functions that use internal synchronization via internal/race.Acquire/Release.
Root Cause
- We only instrument user code via AST transformation
- Go stdlib is pre-compiled - we don't instrument it
iter.Pull uses race.Acquire/Release for internal sync between caller and iterator goroutine
- Our detector doesn't see these sync calls → reports false positives
Example
// iter/iter.go (Go stdlib):
func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func()) {
var pull struct {
racer int // sync variable
}
c := newcoro(func(c *coro) {
race.Acquire(unsafe.Pointer(&pull.racer)) // SYNC!
yield := func(v1 V) bool {
race.Release(unsafe.Pointer(&pull.racer)) // SYNC!
coroswitch(c)
race.Acquire(unsafe.Pointer(&pull.racer)) // SYNC!
return !pull.done
}
})
}
Evidence
Testing on zygomys (uses iter.Pull):
| Detector |
GOMAXPROCS=8, count=100 |
Result |
| TSAN |
100 runs |
PASS - no races |
| Ours |
5 runs |
FAIL - multiple "races" |
TSAN correctly sees the happens-before from iter.Pull. Our detector does not.
Affected stdlib functions
iter.Pull / iter.Pull2 (Go 1.23+)
- Potentially any stdlib using
internal/race.Acquire/Release
Possible Solutions
Short-term (P1):
- Document limitation in README/docs
- Filter reports involving
iter.Pull goroutines (heuristic)
- Warn users when iter.Pull detected in stack trace
Long-term (P2):
- Intercept stdlib sync - Hook into runtime sync primitives
- Compiler integration - Like TSAN, get sync info from compiler
- Hybrid approach - Combine with
-race flag for stdlib coverage
Related
Priority
P1 - This affects correctness. False positives reduce trust in the tool.
Problem
Our detector reports false positive races when user code uses
iter.Pull(Go 1.23+) or other stdlib functions that use internal synchronization viainternal/race.Acquire/Release.Root Cause
iter.Pullusesrace.Acquire/Releasefor internal sync between caller and iterator goroutineExample
Evidence
Testing on zygomys (uses iter.Pull):
TSAN correctly sees the happens-before from iter.Pull. Our detector does not.
Affected stdlib functions
iter.Pull/iter.Pull2(Go 1.23+)internal/race.Acquire/ReleasePossible Solutions
Short-term (P1):
iter.Pullgoroutines (heuristic)Long-term (P2):
-raceflag for stdlib coverageRelated
docs/dev/research-reports/ZYGOMYS_RACE_INVESTIGATION.mdPriority
P1 - This affects correctness. False positives reduce trust in the tool.