Skip to content

Heuristic: Detect iter.Pull sync pattern to avoid false positives #37

@kolkov

Description

@kolkov

Problem

Issue #36 identified that we report false positives when user code uses iter.Pull (Go 1.23+).

Root cause: iter.Pull uses coroswitch() for real synchronization, plus race.Acquire/Release annotations for TSAN. We don't see these annotations because:

  • Without -race flag: internal/race functions are no-op
  • We only instrument user code, not stdlib

Proposed Solution: Heuristic Detection

Detect iter.Pull pattern in stack traces and treat related goroutines as synchronized.

Implementation idea:

// When reporting a race, check if either goroutine has iter.Pull in stack
func (d *Detector) isIterPullSynced(g1, g2 *goroutine.RaceContext) bool {
    // Check for "iter.Pull[...].func1" in stack frames
    for _, frame := range g1.StackFrames {
        if strings.Contains(frame.Function, "iter.Pull") {
            return true
        }
    }
    // Same for g2
    return false
}

// Skip race report if iter.Pull sync detected
if d.isIterPullSynced(currentCtx, previousCtx) {
    return // Don't report - likely false positive
}

Pros:

  • Simple to implement
  • Fixes the immediate false positive problem
  • No need to modify Go toolchain

Cons:

  • Heuristic, not precise
  • May miss real races that happen to involve iter.Pull
  • Need to maintain list of stdlib sync patterns

Alternative Solutions

Approach Complexity Reliability
This heuristic Low Workaround
//go:linkname to intercept coroswitch Medium Fragile
Modify internal/race to call our runtime High Correct
Hybrid: -race for stdlib + ours for user Medium Conflicts?

Questions

  1. Is heuristic approach acceptable for a race detector?
  2. Are there other stdlib functions with similar patterns we should handle?
  3. Is there a better way to intercept stdlib sync without modifying Go toolchain?

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions