Race Detector: Executando e Interpretando Saída
O detector de race do Go instrumenta acessos à memória em tempo de compilação para encontrar leituras e escritas concorrentes não sincronizadas.
Busque em todas as páginas da documentação
O detector de race do Go instrumenta acessos à memória em tempo de compilação para encontrar leituras e escritas concorrentes não sincronizadas.
Execute-o em CI em pacotes que usam goroutines; aprenda a ler seus relatórios para corrigir bugs reais, não para silenciar ruído.
Ative com -race em go test, go run ou go build.
Uma data race ocorre quando duas goroutines acessam a mesma localização de memória, pelo menos uma delas é uma escrita, e não há ordenação happens-before.
Relatórios mostram pilhas de goroutines para ambos os lados da race.
Corrija com mutexes, canais, atômicos ou reestruturando a propriedade - nunca diga "passou uma vez sem -race".
Cartão de receita de referência rápida - pronto para copiar e colar.
go test -race ./...
go run -race .
go build -race -o bin/app .
./bin/app # apenas em staging - builds com race são mais lentos e usam mais memóriaQuando usar isso:
-count=10 paralelo.Código com bug e padrão típico de saída do detector:
package counter
import "sync"
var n int // BUG: não sincronizado
func Inc() { n++ }
func BrokenParallel(wg *sync.WaitGroup) {
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
Inc()
}()
}
}$ go test -race ./...
==================
WARNING: DATA RACE
Write at 0x... by goroutine 7:
example.com/counter.Inc()
example.com/counter.BrokenParallel.func1()
Previous read at 0x... by goroutine 6:
...
==================Versão corrigida:
var (
mu sync.Mutex
n int
)
func Inc() {
mu.Lock()
n++
mu.Unlock()
}O que isso demonstra:
Inc e seus chamadores aparecem nas pilhas - comece lendo a partir dos frames do seu código.-race até que esteja limpo.| Seção | Significado |
|---|---|
Write at / Read at | Tipo de acesso e endereço |
by goroutine N | Pilha de um participante |
Previous read/write | Pilha do outro participante |
Goroutine N created at | Onde a goroutine foi iniciada |
| Padrão | Correção |
|---|---|
| Mapa compartilhado sem lock | Mutex ou passe a propriedade via canal |
| Verificar-então-agir | Bloqueie toda a verificação+ação ou use CAS atômico |
| Race de inicialização preguiçosa | sync.Once |
| Anexar a slice compartilhada | Mutex ou goroutine de escritor única |
# Caça a race intermitente
go test -race -count=50 ./pkg
# Snippet de CI
go test -race -short ./...-race obrigatório para pacotes principais.-parallel 1 - Esconde races. Correção: sincronize o código em teste.-race limpam - Races de lógica permanecem. Correção: atômicos para contadores simples; mutex para invariantes.go test -timeout, detectores de deadlock em staging.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
Testes -race | Verificação de concorrência padrão | Binários de produção |
Mutex + revisão de código | Prevenir races por design | Substituir a execução de -race |
go test -fuzz | Bugs impulsionados por entrada | Races de dados sem concorrência de fuzz |
| Sanitizadores de thread (outras linguagens) | N/A em Go | Código Go - use o detector de race embutido |
Sim - muitas vezes várias vezes mais lentos.
Execute em CI noturno ou por PR para pacotes afetados se a suíte completa for muito lenta.
Sim - races dependem do tempo.
-race força a instrumentação de interlaçamento para revelá-las.
Não para produção sensível à latência.
Use ambientes de staging ou de soak dedicados com builds de -race.
Relatórios ainda mostram pilhas.
Serialize init com sync.Once ou evite globais mutáveis.
A transferência é sincronizada, mas mutar uma struct após enviar um ponteiro ainda causa race se outras goroutines a lerem sem sincronização.
Operações atômicas corretas não causam race na mesma palavra.
Misturar atômicos e mutex em dados sobrepostos ainda é propenso a erros.
Nenhuma supressão oficial como algumas ferramentas C.
Corrija o bug ou refatore o design do teste.
Suportado em linux/amd64, darwin/amd64, darwin/arm64, windows/amd64 e outras portas listadas.
Verifique a documentação do go.dev para a lista atual de plataformas.
Uma race precisa de dois acessos concorrentes.
Cada pilha é a participação de uma goroutine.
Linters capturam algumas APIs propensas a races, mas não substituem -race.
Use ambos em CI.
Versões de Stack: Esta página foi escrita para Go 1.26.x (padrão Green Tea GC, go fix modernizers - verifique o patch na compilação), chi (última versão - verifique na compilação), gin (última versão - verifique na compilação), echo (última versão - verifique na compilação), google.golang.org/grpc (última versão - verifique na compilação), sigs.k8s.io/controller-runtime (última versão - verifique na compilação), kubebuilder (última versão - verifique na compilação), tinygo (última versão - verifique os alvos de placa na compilação), wazero (última versão - verifique na compilação) e golangci-lint (última versão - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 18 de jul. de 2026