This piece explains what data races are, how dynamic race detectors work, and why ThreadSanitizer (TSan) - the de facto detector used by Clang, GCC, Go and others - has important blind spots. It walks through the theory and history of detection algorithms (Eraser, FastTrack, RaceTrack) and describes how TSan evolved through three major versions, with sparse public documentation for the latest iteration. To make the mechanics concrete, an idealized interpreter for a subset of C is implemented in Python alongside a FastTrack-style detector: per-thread monotonic clocks and vector clocks, primitive acquire/release semantics, start/join behavior, and the memory-access checks that reveal concurrent-read/write conflicts.
The hands-on model surfaces concrete limits: algorithmic/design choices in TSan allow it to be overloaded and miss obvious races in realistic deployments. One striking finding is a reliable blind spot past a 255-thread boundary, a practical concern for Go servers that spawn many goroutines. Go also has a specific failure mode: sync.Pool’s slot hashing can hide races between goroutines whose pooled objects map to the same slot. These and related issues are documented in recent research and a PhD chapter; the takeaway is that TSan remains indispensable for finding latent concurrency bugs, but developers must understand its assumptions and blind spots to avoid false negatives.
Summary generated by AI from the linked article. hn.today is not affiliated with Hacker News or Y Combinator.