aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Gerrand <adg@golang.org>2013-06-05 10:20:34 +1000
committerAndrew Gerrand <adg@golang.org>2013-06-05 10:20:34 +1000
commit03290b55e9270f3ecd56a8050692a0e8841e8944 (patch)
tree5d7990d332874da10a552b5e909e112e9f58c5be
parent5f1cf3440237d0ed68e918b51faeba1c42d1ec8a (diff)
downloadgo-03290b55e9270f3ecd56a8050692a0e8841e8944.tar.gz
go-03290b55e9270f3ecd56a8050692a0e8841e8944.zip
[release-branch.go1.1] runtime: fix GC scanning of slices
««« CL 9372044 / 1abed5873071 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 »»» R=cshapiro, iant CC=golang-dev https://golang.org/cl/10027043
-rw-r--r--src/pkg/runtime/gc_test.go24
-rw-r--r--src/pkg/runtime/mgc0.c6
2 files changed, 29 insertions, 1 deletions
diff --git a/src/pkg/runtime/gc_test.go b/src/pkg/runtime/gc_test.go
index 26fc77de11..d40dccb788 100644
--- a/src/pkg/runtime/gc_test.go
+++ b/src/pkg/runtime/gc_test.go
@@ -97,3 +97,27 @@ func TestGcHashmapIndirection(t *testing.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")
+ }
+ }
+}
diff --git a/src/pkg/runtime/mgc0.c b/src/pkg/runtime/mgc0.c
index f9dbdbb4a1..4dfcfca36f 100644
--- a/src/pkg/runtime/mgc0.c
+++ b/src/pkg/runtime/mgc0.c
@@ -799,7 +799,11 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
sliceptr = (Slice*)(stack_top.b + pc[1]);
if(sliceptr->cap != 0) {
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;
break;