Что происходит при запуске приложения с флагом -race в Go?
Что проверяют
Понимаете ли вы, что -race это не статический анализ, а инструментированный прогон, и что именно он считает ошибкой. Попутно проверяют, где вы его включаете: в тестах и нагрузочных прогонах или изредка локально.
Как отвечать
Сборка с -race включает детектор гонок: компилятор вставляет вызовы перед обращениями к памяти, а рантайм ведёт теневую память с историей обращений и граф отношений happens-before, который наполняют события синхронизации: старт горутины, каналы, мьютексы, WaitGroup, sync.Once.
Гонкой считается пара обращений к одному участку памяти из разных горутин, где хотя бы одно на запись и между ними нет happens-before. При срабатывании печатается отчёт: стек чтения, стек записи и стеки создания обеих горутин, чего обычно достаточно, чтобы найти виновника.
go test -race ./...
go build -race -o app ./cmd/appВажные оговорки, которые и хотят услышать:
- детектор динамический, он видит только то, что реально выполнилось в этом прогоне, поэтому тест без конкуренции не найдёт ничего;
- цена высокая: время выполнения и потребление памяти вырастают в разы, обычную прод-сборку так не собирают;
- в
go testнайденная гонка валит тест, а при обычном запуске программа по умолчанию продолжает работать и отчёт легко потерять в логах, поведение настраивается переменнойGORACE.
Отсюда практика: -race в CI на всех тестах плюс прогон с повторами и реальным параллелизмом.
Где спотыкаются
Читают «собралось без предупреждений» как «гонок нет». Отсутствие отчёта говорит только про пути, пройденные в этом запуске, а не про программу целиком.
Второе: ждут, что детектор найдёт любую конкурентную ошибку. Дедлок, потерянное обновление через канал, неверный порядок операций под корректно взятым мьютексом это не data race, и отчёта не будет.
Третье: пишут тест, где горутины запускаются и тут же ждут WaitGroup без настоящей параллельной работы, либо гоняют его один раз. Гонку надо провоцировать: повторами, ростом числа горутин и значением GOMAXPROCS больше единицы.