How does the race detector work, and what are its limitations? Is a "benign" data race ever OK?
Question 234MediumGo 1.22 to 1.25
-race (for go test, go run and go build) instruments every memory access and synchronization operation. It uses ThreadSanitizer's happens-before algorithm, based on vector clocks. When two accesses to the same address come from different goroutines, at least one is a write, and there is no happens-before edge between them, it prints both stacks.
Limitations:
- It finds only races that actually happen during the run, with no false positives. Coverage depends on your tests exercising the concurrent paths, so run with
-countand realistic parallelism. - It costs roughly 2-20x CPU and 5-10x memory, so it is used in CI and canaries, not across a production fleet.
- It only runs on supported OS and architecture combinations (linux, darwin, windows and freebsd on amd64/arm64, among a few others). On most platforms, Linux and Windows included, it needs cgo and a C toolchain; macOS has not needed cgo for it since Go 1.20.
No race is benign in Go.
- Interfaces and slices are multiword, so a racy read can see a type pointer from one write and a data pointer from another. That can segfault or corrupt memory.
- A race on a map triggers
fatal error: concurrent map writes. This fatal error cannot be recovered. - The compiler is free to optimize under the assumption that the program is race-free.
go test -race -count=5 ./...
What the interviewer is looking for: -race in CI, plus the understanding that a clean -race run is not proof that the code is race-free.
More on Concurrency Patterns & sync
- Q232Explain the Go memory model and "happens-before". What synchronization edges does Go guarantee?
- Q233What does this program print?
- Q235Does this counter give the right answer with GOMAXPROCS=1? What about counter++ in general?
- Q236What does this print in Go 1.22+ vs before?
- Q237Implement a generic worker pool with a fixed number of workers, context cancellation, and no goroutine leaks.
- Q238Implement fan-out / fan-in: a generic Merge that combines N channels into one.