mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: fix GC scanning of slices
If a slice points to an array embedded in a struct, the whole struct can be incorrectly scanned as the slice buffer. Fixes #5443. R=cshapiro, iant, r, cshapiro, minux.ma CC=bradfitz, gobot, golang-dev https://golang.org/cl/9372044
This commit is contained in:
parent
9e643ac20e
commit
c6293d2106
2 changed files with 29 additions and 1 deletions
|
|
@ -97,3 +97,27 @@ func TestGcHashmapIndirection(t *testing.T) {
|
||||||
m[a] = T{}
|
m[a] = T{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGcArraySlice(t *testing.T) {
|
||||||
|
type X struct {
|
||||||
|
buf [1]byte
|
||||||
|
nextbuf []byte
|
||||||
|
next *X
|
||||||
|
}
|
||||||
|
var head *X
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
p := &X{}
|
||||||
|
p.buf[0] = 42
|
||||||
|
p.next = head
|
||||||
|
if head != nil {
|
||||||
|
p.nextbuf = head.buf[:]
|
||||||
|
}
|
||||||
|
head = p
|
||||||
|
runtime.GC()
|
||||||
|
}
|
||||||
|
for p := head; p != nil; p = p.next {
|
||||||
|
if p.buf[0] != 42 {
|
||||||
|
t.Fatal("corrupted heap")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -799,7 +799,11 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
||||||
sliceptr = (Slice*)(stack_top.b + pc[1]);
|
sliceptr = (Slice*)(stack_top.b + pc[1]);
|
||||||
if(sliceptr->cap != 0) {
|
if(sliceptr->cap != 0) {
|
||||||
obj = sliceptr->array;
|
obj = sliceptr->array;
|
||||||
objti = pc[2] | PRECISE | LOOP;
|
// Can't use slice element type for scanning,
|
||||||
|
// because if it points to an array embedded
|
||||||
|
// in the beginning of a struct,
|
||||||
|
// we will scan the whole struct as the slice.
|
||||||
|
// So just obtain type info from heap.
|
||||||
}
|
}
|
||||||
pc += 3;
|
pc += 3;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue