On branch of our fork (gpu-fixes branch) need to see if still possible on upstream/main.
`
Data Race Summary
Writer (goroutine 123) - assignInterpreter() at line 242:
pm.interpreters[pid][key] = instance
Reader (goroutine 134) - MaybeNotifyAPMAgent() at lines 310-317:
pidInterp, ok := pm.interpreters[rawTrace.PID]
pm.mu.RUnlock() // Lock released here!
...
for _, mapping := range pidInterp { // Iterating without lock
The Bug:
- MaybeNotifyAPMAgent gets a reference to the inner map pm.interpreters[pid] while holding RLock
- It then releases the lock at line 311
- It then iterates over pidInterp at line 317 without any lock
- Meanwhile, assignInterpreter writes to that same inner map
The inner map is a reference type, so pidInterp points to the same underlying map that assignInterpreter is modifying. Releasing the lock before iterating creates the race window.
Fix options:
- Hold the RLock during the entire iteration (may cause lock contention)
- Copy the map values into a slice before releasing the lock
- Use a different synchronization strategy for the inner map
`
On branch of our fork (gpu-fixes branch) need to see if still possible on upstream/main.
`
Data Race Summary
Writer (goroutine 123) - assignInterpreter() at line 242:
pm.interpreters[pid][key] = instance
Reader (goroutine 134) - MaybeNotifyAPMAgent() at lines 310-317:
pidInterp, ok := pm.interpreters[rawTrace.PID]
pm.mu.RUnlock() // Lock released here!
...
for _, mapping := range pidInterp { // Iterating without lock
The Bug:
The inner map is a reference type, so pidInterp points to the same underlying map that assignInterpreter is modifying. Releasing the lock before iterating creates the race window.
Fix options:
`