Race detector
Сергей запустил go test -race в dev-окружении, и детектор нашёл гонку конфигурации за пару минут: в отчёте стояли оба обращения и стек-трейсы. Недельное расследование схлопнулось в один прогон.
go test -race инструментирует обращения к памяти и ловит реальные гонки данных — те пары обращений, между которыми нет happens-before.
Гонка, которую видно не всегда
var counter int
func inc() {
counter++ // read-modify-write без синхронизации
}
Несколько горутин, зовущих inc, теряют инкременты. Баг вероятностный: на малой нагрузке всё «работает», а под реальной — сыплется. Race detector ловит его надёжно — когда оба конфликтующих обращения реально исполнились в прогоне.
Как запускать
go test -race ./...
go run -race main.go
go build -race -o app .
-race компилирует программу с инструментированием: каждое обращение к памяти записывается, и при обнаружении двух обращений без синхронизации печатается отчёт — оба места, стек-трейсы, и как горутины создавались. Это встроенный в тулчейн ThreadSanitizer-подход, без внешних зависимостей.
Как читать отчёт
WARNING: DATA RACE
Write at ... by goroutine 7:
main.inc() counter.go:12
Previous read at ... by goroutine 6:
main.inc() counter.go:12
Отчёт показывает: что за операция (запись/чтение), где в коде, какая горутина, и вторую половину пары — обращение, с которым случилась гонка. Остаётся добавить синхронизацию — мьютекс или атомик. Детектор не подсказывает, что именно чинить, но точно указывает, где.
Вы узнаете:
- почему
-raceловит гонку, даже если она не проявилась - как
GORACEнастраивает отчёт
Проверьте себя
Ловит ли -race гонку, которая в этом прогоне «не проявилась»?
Как запустить race detector?
Поймает ли -race гонку в ветке, по которой тесты не ходят?
правильных ответов
-race ловит data race на прогоне теста: два обращения без happens-before. Отчёт — оба места гонки. Чинится синхронизацией.
10 000 ₽ · 60 минут · онлайн