Skip to content

bug(escape): Pointer dereferences incorrectly skipped when pointer doesn't escape #27

@kolkov

Description

@kolkov

Summary

Escape analysis incorrectly skips instrumentation for pointer dereferences when the pointer variable itself doesn't escape, but the memory it points to can be shared.

Reported by

@thepudds in golang/go#6508 (comment)

Reproduction

//go:noinline
func update(ptr *int) { // -gcflags=-m: "ptr does not escape"
    *ptr++
}

func main() {
    var shared int
    var wg sync.WaitGroup
    for range 2 {
        wg.Go(func() {
            for range 100 {
                update(&shared)
            }
        })
    }
    wg.Wait()
}

Expected

Race detected on *ptr++ (TSAN reports correctly)

Actual

No race reported (v0.8.1)

Root Cause

Our escape analysis skips instrumentation when a variable "doesn't escape", but:

  • ptr is a local parameter (doesn't escape)
  • *ptr dereferences to shared which IS accessed by multiple goroutines

Fix

Only skip direct local variable access (x = 5), NOT pointer dereferences (*ptr = 5).

Pointer dereferences must always be instrumented regardless of escape analysis.

Priority

P0 - Critical regression in v0.8.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions