mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: fix race instrumentation of append
typedslicecopy is another write barrier that is not understood by racewalk. It seems quite complex to handle it in the compiler, so instead just instrument it in runtime. Update #9796 Change-Id: I0eb6abf3a2cd2491a338fab5f7da22f01bf7e89b Reviewed-on: https://go-review.googlesource.com/4370 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
c1bbf0a2ea
commit
ed8cc5cf9b
3 changed files with 103 additions and 0 deletions
|
|
@ -205,6 +205,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
|
|||
case OCALLFUNC:
|
||||
// Instrument dst argument of runtime.writebarrier* calls
|
||||
// as we do not instrument runtime code.
|
||||
// typedslicecopy is instrumented in runtime.
|
||||
if(n->left->sym != S && n->left->sym->pkg == runtimepkg &&
|
||||
(strncmp(n->left->sym->name, "writebarrier", 12) == 0 || strcmp(n->left->sym->name, "typedmemmove") == 0)) {
|
||||
// Find the dst argument.
|
||||
|
|
|
|||
|
|
@ -328,6 +328,13 @@ func typedslicecopy(typ *_type, dst, src slice) int {
|
|||
dstp := unsafe.Pointer(dst.array)
|
||||
srcp := unsafe.Pointer(src.array)
|
||||
|
||||
if raceenabled {
|
||||
callerpc := getcallerpc(unsafe.Pointer(&typ))
|
||||
pc := funcPC(slicecopy)
|
||||
racewriterangepc(dstp, uintptr(n)*typ.size, callerpc, pc)
|
||||
racereadrangepc(srcp, uintptr(n)*typ.size, callerpc, pc)
|
||||
}
|
||||
|
||||
if !needwb() {
|
||||
memmove(dstp, srcp, uintptr(n)*typ.size)
|
||||
return int(n)
|
||||
|
|
|
|||
95
src/runtime/race/testdata/slice_test.go
vendored
95
src/runtime/race/testdata/slice_test.go
vendored
|
|
@ -144,6 +144,54 @@ func TestNoRaceSliceCopyRead(t *testing.T) {
|
|||
<-ch
|
||||
}
|
||||
|
||||
func TestRacePointerSliceCopyRead(t *testing.T) {
|
||||
ch := make(chan bool, 1)
|
||||
a := make([]*int, 10)
|
||||
b := make([]*int, 10)
|
||||
go func() {
|
||||
_ = a[5]
|
||||
ch <- true
|
||||
}()
|
||||
copy(a, b)
|
||||
<-ch
|
||||
}
|
||||
|
||||
func TestNoRacePointerSliceWriteCopy(t *testing.T) {
|
||||
ch := make(chan bool, 1)
|
||||
a := make([]*int, 10)
|
||||
b := make([]*int, 10)
|
||||
go func() {
|
||||
a[5] = new(int)
|
||||
ch <- true
|
||||
}()
|
||||
copy(a[:5], b[:5])
|
||||
<-ch
|
||||
}
|
||||
|
||||
func TestRacePointerSliceCopyWrite2(t *testing.T) {
|
||||
ch := make(chan bool, 1)
|
||||
a := make([]*int, 10)
|
||||
b := make([]*int, 10)
|
||||
go func() {
|
||||
b[5] = new(int)
|
||||
ch <- true
|
||||
}()
|
||||
copy(a, b)
|
||||
<-ch
|
||||
}
|
||||
|
||||
func TestNoRacePointerSliceCopyRead(t *testing.T) {
|
||||
ch := make(chan bool, 1)
|
||||
a := make([]*int, 10)
|
||||
b := make([]*int, 10)
|
||||
go func() {
|
||||
_ = b[5]
|
||||
ch <- true
|
||||
}()
|
||||
copy(a, b)
|
||||
<-ch
|
||||
}
|
||||
|
||||
func TestNoRaceSliceWriteSlice2(t *testing.T) {
|
||||
ch := make(chan bool, 1)
|
||||
a := make([]float64, 10)
|
||||
|
|
@ -395,6 +443,53 @@ func TestRaceSliceAppendString(t *testing.T) {
|
|||
<-c
|
||||
}
|
||||
|
||||
func TestRacePointerSliceAppend(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
s := make([]*int, 10, 20)
|
||||
go func() {
|
||||
_ = append(s, new(int))
|
||||
c <- true
|
||||
}()
|
||||
_ = append(s, new(int))
|
||||
<-c
|
||||
}
|
||||
|
||||
func TestRacePointerSliceAppendWrite(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
s := make([]*int, 10)
|
||||
go func() {
|
||||
_ = append(s, new(int))
|
||||
c <- true
|
||||
}()
|
||||
s[0] = new(int)
|
||||
<-c
|
||||
}
|
||||
|
||||
func TestRacePointerSliceAppendSlice(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
s := make([]*int, 10)
|
||||
go func() {
|
||||
s2 := make([]*int, 10)
|
||||
_ = append(s, s2...)
|
||||
c <- true
|
||||
}()
|
||||
s[0] = new(int)
|
||||
<-c
|
||||
}
|
||||
|
||||
func TestRacePointerSliceAppendSlice2(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
s := make([]*int, 10)
|
||||
s2foobar := make([]*int, 10)
|
||||
go func() {
|
||||
_ = append(s, s2foobar...)
|
||||
c <- true
|
||||
}()
|
||||
println("WRITE:", &s2foobar[5])
|
||||
s2foobar[5] = nil
|
||||
<-c
|
||||
}
|
||||
|
||||
func TestNoRaceSliceIndexAccess(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
s := make([]int, 10)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue