2
"Title": "Data Race Detector",
6
<h2 id="Introduction">Introduction</h2>
9
Data races are among the most common and hardest to debug types of bugs in concurrent systems.
10
A data race occurs when two goroutines access the same variable concurrently and at least one of the accesses is a write.
11
See the <a href="/ref/mem/">The Go Memory Model</a> for details.
15
Here is an example of a data race that can lead to crashes and memory corruption:
21
m := make(map[string]string)
23
m["1"] = "a" // First conflicting access.
26
m["2"] = "b" // Second conflicting access.
34
<h2 id="Usage">Usage</h2>
37
To help diagnose such bugs, Go includes a built-in data race detector.
38
To use it, add the <code>-race</code> flag to the go command:
42
$ go test -race mypkg // to test the package
43
$ go run -race mysrc.go // to run the source file
44
$ go build -race mycmd // to build the command
45
$ go install -race mypkg // to install the package
48
<h2 id="Report_Format">Report Format</h2>
51
When the race detector finds a data race in the program, it prints a report.
52
The report contains stack traces for conflicting accesses, as well as stacks where the involved goroutines were created.
58
Read by goroutine 185:
59
net.(*pollServer).AddFD()
60
src/pkg/net/fd_unix.go:89 +0x398
61
net.(*pollServer).WaitWrite()
62
src/pkg/net/fd_unix.go:247 +0x45
64
src/pkg/net/fd_unix.go:540 +0x4d4
66
src/pkg/net/net.go:129 +0x101
68
src/pkg/net/timeout_test.go:603 +0xaf
70
Previous write by goroutine 184:
71
net.setWriteDeadline()
72
src/pkg/net/sockopt_posix.go:135 +0xdf
74
src/pkg/net/sockopt_posix.go:144 +0x9c
75
net.(*conn).SetDeadline()
76
src/pkg/net/net.go:161 +0xe3
78
src/pkg/net/timeout_test.go:616 +0x3ed
80
Goroutine 185 (running) created at:
82
src/pkg/net/timeout_test.go:609 +0x288
84
Goroutine 184 (running) created at:
85
net.TestProlongTimeout()
86
src/pkg/net/timeout_test.go:618 +0x298
88
src/pkg/testing/testing.go:301 +0xe8
91
<h2 id="Options">Options</h2>
94
The <code>GORACE</code> environment variable sets race detector options.
99
GORACE="option1=val1 option2=val2"
108
<code>log_path</code> (default <code>stderr</code>): The race detector writes
109
its report to a file named <code>log_path.<em>pid</em></code>.
110
The special names <code>stdout</code>
111
and <code>stderr</code> cause reports to be written to standard output and
112
standard error, respectively.
116
<code>exitcode</code> (default <code>66</code>): The exit status to use when
117
exiting after a detected race.
121
<code>strip_path_prefix</code> (default <code>""</code>): Strip this prefix
122
from all reported file paths, to make reports more concise.
126
<code>history_size</code> (default <code>1</code>): The per-goroutine memory
127
access history is <code>32K * 2**history_size elements</code>.
128
Increasing this value can avoid a "failed to restore the stack" error in reports, at the
129
cost of increased memory usage.
138
$ GORACE="log_path=/tmp/race/report strip_path_prefix=/my/go/sources/" go test -race
141
<h2 id="Excluding_Tests">Excluding Tests</h2>
144
When you build with <code>-race</code> flag, the <code>go</code> command defines additional
145
<a href="/pkg/go/build/#hdr-Build_Constraints">build tag</a> <code>race</code>.
146
You can use the tag to exclude some code and tests when running the race detector.
155
// The test contains a data race. See issue 123.
156
func TestFoo(t *testing.T) {
160
// The test fails under the race detector due to timeouts.
161
func TestBar(t *testing.T) {
165
// The test takes too long under the race detector.
166
func TestBaz(t *testing.T) {
171
<h2 id="How_To_Use">How To Use</h2>
174
To start, run your tests using the race detector (<code>go test -race</code>).
175
The race detector only finds races that happen at runtime, so it can't find
176
races in code paths that are not executed.
177
If your tests have incomplete coverage,
178
you may find more races by running a binary built with <code>-race</code> under a realistic
182
<h2 id="Typical_Data_Races">Typical Data Races</h2>
185
Here are some typical data races. All of them can be detected with the race detector.
188
<h3 id="Race_on_loop_counter">Race on loop counter</h3>
192
var wg sync.WaitGroup
194
for i := 0; i < 5; i++ {
196
fmt.Println(i) // Not the 'i' you are looking for.
205
The variable <code>i</code> in the function literal is the same variable used by the loop, so
206
the read in the goroutine races with the loop increment.
207
(This program typically prints 55555, not 01234.)
208
The program can be fixed by making a copy of the variable:
213
var wg sync.WaitGroup
215
for i := 0; i < 5; i++ {
217
fmt.Println(j) // Good. Read local copy of the loop counter.
225
<h3 id="Accidentally_shared_variable">Accidentally shared variable</h3>
228
// ParallelWrite writes data to file1 and file2, returns the errors.
229
func ParallelWrite(data []byte) chan error {
230
res := make(chan error, 2)
231
f1, err := os.Create("file1")
236
// This err is shared with the main goroutine,
237
// so the write races with the write below.
238
_, err = f1.Write(data)
243
f2, err := os.Create("file2") // The second conflicting write to err.
248
_, err = f2.Write(data)
258
The fix is to introduce new variables in the goroutines (note the use of <code>:=</code>):
263
_, err := f1.Write(data)
265
_, err := f2.Write(data)
269
<h3 id="Unprotected_global_variable">Unprotected global variable</h3>
272
If the following code is called from several goroutines, it leads to races on the <code>service</code> map.
273
Concurrent reads and writes of the same map are not safe:
277
var service map[string]net.Addr
279
func RegisterService(name string, addr net.Addr) {
283
func LookupService(name string) net.Addr {
289
To make the code safe, protect the accesses with a mutex:
294
service map[string]net.Addr
298
func RegisterService(name string, addr net.Addr) {
300
defer serviceMu.Unlock()
304
func LookupService(name string) net.Addr {
306
defer serviceMu.Unlock()
311
<h3 id="Primitive_unprotected_variable">Primitive unprotected variable</h3>
314
Data races can happen on variables of primitive types as well (<code>bool</code>, <code>int</code>, <code>int64</code>, etc.),
319
type Watchdog struct{ last int64 }
321
func (w *Watchdog) KeepAlive() {
322
w.last = time.Now().UnixNano() // First conflicting access.
325
func (w *Watchdog) Start() {
328
time.Sleep(time.Second)
329
// Second conflicting access.
330
if w.last < time.Now().Add(-10*time.Second).UnixNano() {
331
fmt.Println("No keepalives for 10 seconds. Dying.")
340
Even such "innocent" data races can lead to hard-to-debug problems caused by
341
non-atomicity of the memory accesses,
342
interference with compiler optimizations,
343
or reordering issues accessing processor memory .
347
A typical fix for this race is to use a channel or a mutex.
348
To preserve the lock-free behavior, one can also use the
349
<a href="/pkg/sync/atomic/"><code>sync/atomic</code></a> package.
353
type Watchdog struct{ last int64 }
355
func (w *Watchdog) KeepAlive() {
356
atomic.StoreInt64(&w.last, time.Now().UnixNano())
359
func (w *Watchdog) Start() {
362
time.Sleep(time.Second)
363
if atomic.LoadInt64(&w.last) < time.Now().Add(-10*time.Second).UnixNano() {
364
fmt.Println("No keepalives for 10 seconds. Dying.")
372
<h2 id="Supported_Systems">Supported Systems</h2>
375
The race detector runs on <code>darwin/amd64</code>, <code>linux/amd64</code>, and <code>windows/amd64</code>.
378
<h2 id="Runtime_Overheads">Runtime Overhead</h2>
381
The cost of race detection varies by program, but for a typical program, memory
382
usage may increase by 5-10x and execution time by 2-20x.