]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/race: tell race detector what memory Read/Write syscalls touch
authorDmitriy Vyukov <dvyukov@google.com>
Mon, 10 Jun 2013 18:40:35 +0000 (22:40 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Mon, 10 Jun 2013 18:40:35 +0000 (22:40 +0400)
Fixes #5567.

R=golang-dev, dave, iant
CC=golang-dev
https://golang.org/cl/10085043

src/pkg/runtime/race.c
src/pkg/runtime/race.go
src/pkg/runtime/race/testdata/mop_test.go
src/pkg/syscall/race.go
src/pkg/syscall/race0.go
src/pkg/syscall/syscall_plan9.go
src/pkg/syscall/syscall_unix.go
src/pkg/syscall/syscall_windows.go

index ce2a85678110eed9c79286afb4d0a0fe327f16b3..3a094896f95f23791931d35046002120d3984379 100644 (file)
@@ -330,6 +330,22 @@ runtime·RaceWrite(void *addr)
        memoryaccess(addr, 0, (uintptr)runtime·getcallerpc(&addr), true);
 }
 
+// func RaceReadRange(addr unsafe.Pointer, len int)
+#pragma textflag 7
+void
+runtime·RaceReadRange(void *addr, intgo len)
+{
+       rangeaccess(addr, len, 1, 0, (uintptr)runtime·getcallerpc(&addr), false);
+}
+
+// func RaceWriteRange(addr unsafe.Pointer, len int)
+#pragma textflag 7
+void
+runtime·RaceWriteRange(void *addr, intgo len)
+{
+       rangeaccess(addr, len, 1, 0, (uintptr)runtime·getcallerpc(&addr), true);
+}
+
 // func RaceDisable()
 void
 runtime·RaceDisable(void)
index 1d64ba3894e4f3dd17757938e238ecbf15711642..2a9124d642dc4caa286378de1f029f226aecc3e2 100644 (file)
@@ -24,6 +24,8 @@ func RaceReleaseMerge(addr unsafe.Pointer)
 
 func RaceRead(addr unsafe.Pointer)
 func RaceWrite(addr unsafe.Pointer)
+func RaceReadRange(addr unsafe.Pointer, len int)
+func RaceWriteRange(addr unsafe.Pointer, len int)
 
 func RaceSemacquire(s *uint32)
 func RaceSemrelease(s *uint32)
index 6d30989193e6be2808dcc14557d61fd056e93edb..de2576cf6f8852d1b74f28ef692854a610afa517 100644 (file)
@@ -5,8 +5,11 @@
 package race_test
 
 import (
+       "crypto/sha1"
        "errors"
        "fmt"
+       "io"
+       "os"
        "runtime"
        "sync"
        "testing"
@@ -1627,3 +1630,43 @@ func TestRaceNestedStruct(t *testing.T) {
        y.x.y = 42
        <-c
 }
+
+func TestRaceIssue5567(t *testing.T) {
+       defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+       in := make(chan []byte)
+       res := make(chan error)
+       go func() {
+               var err error
+               defer func() {
+                       close(in)
+                       res <- err
+               }()
+               path := "mop_test.go"
+               f, err := os.Open(path)
+               if err != nil {
+                       return
+               }
+               defer f.Close()
+               var n, total int
+               b := make([]byte, 17) // the race is on b buffer
+               for err == nil {
+                       n, err = f.Read(b)
+                       total += n
+                       if n > 0 {
+                               in <- b[:n]
+                       }
+               }
+               if err == io.EOF {
+                       err = nil
+               }
+       }()
+       h := sha1.New()
+       for b := range in {
+               h.Write(b)
+       }
+       _ = h.Sum(nil)
+       err := <-res
+       if err != nil {
+               t.Fatal(err)
+       }
+}
index 81778846f26e1411f14d56e8ddb50bd4de8b83e0..e69c1119a215204c1b1982b7a7c4f6cf86a3bd53 100644 (file)
@@ -20,3 +20,11 @@ func raceAcquire(addr unsafe.Pointer) {
 func raceReleaseMerge(addr unsafe.Pointer) {
        runtime.RaceReleaseMerge(addr)
 }
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+       runtime.RaceReadRange(addr, len)
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+       runtime.RaceWriteRange(addr, len)
+}
index e94fb47afbeab6d77e49313b8797818abe54f958..b02f882fd05a07b403bd00b1f38b648fb097821c 100644 (file)
@@ -17,3 +17,9 @@ func raceAcquire(addr unsafe.Pointer) {
 
 func raceReleaseMerge(addr unsafe.Pointer) {
 }
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+}
index bc2505758e4897aba8e0b80c19cdf8e03673f3a5..2e1c064c46a5b65541344add12f814579eb434ae 100644 (file)
@@ -120,17 +120,10 @@ func Getppid() (ppid int) {
 }
 
 func Read(fd int, p []byte) (n int, err error) {
-       n, err = Pread(fd, p, -1)
-       if raceenabled && err == nil {
-               raceAcquire(unsafe.Pointer(&ioSync))
-       }
-       return
+       return Pread(fd, p, -1)
 }
 
 func Write(fd int, p []byte) (n int, err error) {
-       if raceenabled {
-               raceReleaseMerge(unsafe.Pointer(&ioSync))
-       }
        return Pwrite(fd, p, -1)
 }
 
index fee1fc491fd3c09368634f28afd5ec437eaf2b86..f29395b2db7265d5d84a54d7fc9c052df2c1817f 100644 (file)
@@ -130,8 +130,13 @@ func (s Signal) String() string {
 
 func Read(fd int, p []byte) (n int, err error) {
        n, err = read(fd, p)
-       if raceenabled && err == nil {
-               raceAcquire(unsafe.Pointer(&ioSync))
+       if raceenabled {
+               if n > 0 {
+                       raceWriteRange(unsafe.Pointer(&p[0]), n)
+               }
+               if err == nil {
+                       raceAcquire(unsafe.Pointer(&ioSync))
+               }
        }
        return
 }
@@ -140,7 +145,11 @@ func Write(fd int, p []byte) (n int, err error) {
        if raceenabled {
                raceReleaseMerge(unsafe.Pointer(&ioSync))
        }
-       return write(fd, p)
+       n, err = write(fd, p)
+       if raceenabled && n > 0 {
+               raceReadRange(unsafe.Pointer(&p[0]), n)
+       }
+       return
 }
 
 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
index d7c3265a140d0eb9df91f65d975b0a0bf5497425..4c7f34e9576cf62fa05f2787aebf80df31118fbd 100644 (file)
@@ -272,6 +272,9 @@ func Read(fd Handle, p []byte) (n int, err error) {
                return 0, e
        }
        if raceenabled {
+               if done > 0 {
+                       raceWriteRange(unsafe.Pointer(&p[0]), int(done))
+               }
                raceAcquire(unsafe.Pointer(&ioSync))
        }
        return int(done), nil
@@ -286,6 +289,9 @@ func Write(fd Handle, p []byte) (n int, err error) {
        if e != nil {
                return 0, e
        }
+       if raceenabled && done > 0 {
+               raceReadRange(unsafe.Pointer(&p[0]), int(done))
+       }
        return int(done), nil
 }