diff options
author | Andrew Gerrand <adg@golang.org> | 2013-06-05 10:20:34 +1000 |
---|---|---|
committer | Andrew Gerrand <adg@golang.org> | 2013-06-05 10:20:34 +1000 |
commit | 03290b55e9270f3ecd56a8050692a0e8841e8944 (patch) | |
tree | 5d7990d332874da10a552b5e909e112e9f58c5be | |
parent | 5f1cf3440237d0ed68e918b51faeba1c42d1ec8a (diff) | |
download | go-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.go | 24 | ||||
-rw-r--r-- | src/pkg/runtime/mgc0.c | 6 |
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; |