]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix false race report during tracing
authorDmitry Vyukov <dvyukov@google.com>
Tue, 3 Feb 2015 10:01:09 +0000 (13:01 +0300)
committerDmitry Vyukov <dvyukov@google.com>
Tue, 3 Feb 2015 15:41:41 +0000 (15:41 +0000)
Currently race detector produces the following reports on pprof tests:

WARNING: DATA RACE
Read by goroutine 4:
  runtime/pprof_test.TestTraceStartStop()
      src/runtime/pprof/trace_test.go:38 +0x1da
  testing.tRunner()
      src/testing/testing.go:448 +0x13a

Previous write by goroutine 5:
  bytes.(*Buffer).grow()
      src/bytes/buffer.go:102 +0x190
  bytes.(*Buffer).Write()
      src/bytes/buffer.go:127 +0x75
  runtime/pprof.funcĀ·002()
      src/runtime/pprof/pprof.go:633 +0xae

Trace writer goroutine synchronizes with StopTrace
using trace.shutdownSema runtime semaphore.
But race detector does not see that synchronization
and so produces false reports.
Teach race detector about the synchronization.

Change-Id: I1219817325d4e16b423f29a0cbee94c929793881
Reviewed-on: https://go-review.googlesource.com/3746
Reviewed-by: Russ Cox <rsc@golang.org>
src/runtime/trace.go

index 5b168c7bfc95816719489aa7ec4639685e40a0fc..e7937b3d17b653f28c71950b8c39fb0f1e3f6be4 100644 (file)
@@ -231,6 +231,9 @@ func StopTrace() {
        // The world is started but we've set trace.shutdown, so new tracing can't start.
        // Wait for the trace reader to flush pending buffers and stop.
        semacquire(&trace.shutdownSema, false)
+       if raceenabled {
+               raceacquire(unsafe.Pointer(&trace.shutdownSema))
+       }
 
        // The lock protects us from races with StartTrace/StopTrace because they do stop-the-world.
        lock(&trace.lock)
@@ -331,6 +334,12 @@ func ReadTrace() []byte {
        if trace.shutdown {
                trace.lockOwner = nil
                unlock(&trace.lock)
+               if raceenabled {
+                       // Model synchronization on trace.shutdownSema, which race
+                       // detector does not see. This is required to avoid false
+                       // race reports on writer passed to pprof.StartTrace.
+                       racerelease(unsafe.Pointer(&trace.shutdownSema))
+               }
                // trace.enabled is already reset, so can call traceable functions.
                semrelease(&trace.shutdownSema)
                return nil