racedetector

module
v0.8.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 19, 2025 License: MIT

README

Pure-Go Race Detector

Go Version Release CI Go Report Card Coverage License GoDoc

Pure Go race detector that works with CGO_ENABLED=0. Drop-in replacement for go build -race and go test -race.


The Problem

Go's race detector requires CGO and ThreadSanitizer:

$ CGO_ENABLED=0 go build -race main.go
race detector requires cgo; enable cgo by setting CGO_ENABLED=1

This blocks race detection for:

  • AWS Lambda / Google Cloud Functions
  • FROM scratch Docker images
  • Cross-compilation to embedded systems
  • Alpine Linux containers
  • WebAssembly targets
  • Hermetic builds

This project solves it. Pure Go implementation, no CGO required.


Installation

go install github.com/kolkov/racedetector/cmd/racedetector@latest

Requirements: Go 1.24+


Usage

# Build with race detection (replaces: go build -race)
racedetector build -o myapp main.go

# Run with race detection (replaces: go run -race)
racedetector run main.go

# Test with race detection (replaces: go test -race)
racedetector test ./...
racedetector test -v -run TestFoo ./pkg/...

# Toolexec mode (for complex build systems)
go build -toolexec="racedetector toolexec" ./...

All standard go build, go run, and go test flags are supported.

v0.8.0+: Escape analysis integration reduces false positives by 30-50%.


Example

Buggy code:

package main

import "sync"

var counter int

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            counter++ // DATA RACE
        }()
    }
    wg.Wait()
}

Detection:

$ racedetector build -o app main.go && ./app
==================
WARNING: DATA RACE
Write at 0xc00000a0b8 by goroutine 7:
  main.main.func1 (main.go:13)
Previous Write at 0xc00000a0b8 by goroutine 6:
  main.main.func1 (main.go:13)
==================

How It Works

Implements the FastTrack algorithm (Flanagan & Freund, PLDI 2009):

  1. AST Instrumentation - Parses Go source, inserts race detection calls
  2. Shadow Memory - Tracks access history for every memory location
  3. Vector Clocks - Maintains happens-before relationships across goroutines
  4. Sync Primitive Tracking - Respects Mutex, Channel, WaitGroup synchronization

Architecture:

Source Code → AST Parser → Instrumentation → go build → Static Binary
                                                            ↓
                                                    Runtime Detection

Performance

Metric racedetector Go TSAN
Goroutine ID extraction 1.73 ns <1 ns
VectorClock operations 11-15 ns -
Shadow memory access 2-4 ns -
Hot path overhead 2-5% 5-10x
Max goroutines 65,536 Unlimited

Assembly-optimized goroutine ID extraction on amd64/arm64. Automatic fallback for other platforms.


Test Coverage

Ported 359 test scenarios from Go's official race detector test suite:

  • Write-write and read-write races
  • Mutex, Channel, WaitGroup synchronization
  • Struct fields, slices, maps, arrays
  • Closures, defer, panic/recover
  • Atomic operations, type assertions

100% pass rate with GOMAXPROCS=1 (same configuration as Go's official tests).


Limitations

  • Performance overhead higher than ThreadSanitizer for some workloads
  • Struct field access via dot notation has limited coverage
  • Assembly optimization only on amd64/arm64 (fallback available)
Atomic Operations

Like Go's built-in race detector (ThreadSanitizer), this tool is a dynamic race detector based on happens-before analysis. It cannot detect races that depend on:

  • Compiler/CPU memory reordering - The detector observes actual execution order, not all possible reorderings
  • Weak memory model semantics - Atomic operations provide acquire/release barriers, but the detector uses full synchronization for tracking

This is a fundamental limitation of all dynamic race detectors, not specific to this implementation. For detecting memory model violations, consider static analysis tools or formal verification.

For more details, see Go Race Detector documentation.


Documentation


Contributing

Contributions welcome! See CONTRIBUTING.md for guidelines.

Current priorities:

  • Testing in diverse environments
  • Bug reports and edge cases
  • Documentation improvements

Maintainers

  • @kolkov - Creator & Lead Maintainer

Acknowledgments

Research:

  • Cormac Flanagan & Stephen Freund - FastTrack algorithm (PLDI 2009)
  • Dmitry Vyukov - ThreadSanitizer and Go race detector integration
  • Go Team - Original race detector implementation

Community Contributors:


License

MIT License - see LICENSE


Support

Goal: Integration into official Go toolchain. Your feedback helps make the case.

Directories

Path Synopsis
cmd
racedetector command
build.go implements the 'racedetector build' command.
build.go implements the 'racedetector build' command.
racedetector/instrument
Package instrument - BigFoot static coalescing for race detection optimization.
Package instrument - BigFoot static coalescing for race detection optimization.
racedetector/runtime
Package runtime provides runtime library linking for instrumented code.
Package runtime provides runtime library linking for instrumented code.
examples
build_test command
channel_sync command
Package main demonstrates CORRECT channel-based synchronization.
Package main demonstrates CORRECT channel-based synchronization.
dogfooding command
Package main demonstrates a simple data race for dogfooding test.
Package main demonstrates a simple data race for dogfooding test.
init_fini command
integration command
Package main demonstrates end-to-end usage of the Pure-Go Race Detector.
Package main demonstrates end-to-end usage of the Pure-Go Race Detector.
mutex_protected command
Package main demonstrates CORRECT mutex-protected concurrent access.
Package main demonstrates CORRECT mutex-protected concurrent access.
race_report command
Package main demonstrates race report formatting.
Package main demonstrates race report formatting.
stack_trace_demo command
Package main demonstrates stack trace capture in race reports.
Package main demonstrates stack trace capture in race reports.
stack_trace_research command
Package main demonstrates runtime.Callers() for stack trace capture.
Package main demonstrates runtime.Callers() for stack trace capture.
internal
race/api
Package api provides the public runtime API for the Pure-Go Race Detector.
Package api provides the public runtime API for the Pure-Go Race Detector.
race/detector
Package detector implements the core FastTrack race detection algorithm.
Package detector implements the core FastTrack race detection algorithm.
race/epoch
Package epoch implements 64-bit logical timestamps for FastTrack race detector.
Package epoch implements 64-bit logical timestamps for FastTrack race detector.
race/goroutine
Package goroutine implements per-goroutine race detection state for FastTrack.
Package goroutine implements per-goroutine race detection state for FastTrack.
race/shadowmem
Package shadowmem implements shadow memory cells for FastTrack race detection.
Package shadowmem implements shadow memory cells for FastTrack race detection.
race/stackdepot
Package stackdepot implements stack trace storage and deduplication for race reports.
Package stackdepot implements stack trace storage and deduplication for race reports.
race/syncshadow
Package syncshadow implements shadow memory for synchronization primitives.
Package syncshadow implements shadow memory for synchronization primitives.
race/vectorclock
Package vectorclock implements vector clocks for tracking happens-before relations.
Package vectorclock implements vector clocks for tracking happens-before relations.
Package race provides the public API for the Pure-Go race detector.
Package race provides the public API for the Pure-Go race detector.