]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.1] runtime: fix GC scanning of slices
authorAndrew Gerrand <adg@golang.org>
Wed, 5 Jun 2013 00:20:34 +0000 (10:20 +1000)
committerAndrew Gerrand <adg@golang.org>
Wed, 5 Jun 2013 00:20:34 +0000 (10:20 +1000)
««« 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

src/pkg/runtime/gc_test.go
src/pkg/runtime/mgc0.c

index 26fc77de11f6885eefd3b8fcca121067e04fac80..d40dccb788861b19917631688cfa03b24d5aadc3 100644 (file)
@@ -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")
+               }
+       }
+}
index f9dbdbb4a111d917b8d71f56ae83bf754f9986a3..4dfcfca36fdecbbf626b6629c7551c1a0c9e46ea 100644 (file)
@@ -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;