]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: prevent the GC from seeing the content of a frame in runfinq()
authorJan Ziak <0xe2.0x9a.0x9b@gmail.com>
Thu, 25 Apr 2013 11:39:09 +0000 (13:39 +0200)
committerJan Ziak <0xe2.0x9a.0x9b@gmail.com>
Thu, 25 Apr 2013 11:39:09 +0000 (13:39 +0200)
Fixes #5348.

R=golang-dev, dvyukov
CC=golang-dev
https://golang.org/cl/8954044

src/pkg/runtime/mgc0.c
test/fixedbugs/issue5348.go [new file with mode: 0644]

index f9dbdbb4a111d917b8d71f56ae83bf754f9986a3..6369da2720cc12d5d406fc7346f51804a68f966f 100644 (file)
@@ -2191,7 +2191,7 @@ runfinq(void)
                                framesz = sizeof(uintptr) + f->nret;
                                if(framecap < framesz) {
                                        runtime·free(frame);
-                                       frame = runtime·mal(framesz);
+                                       frame = runtime·mallocgc(framesz, FlagNoPointers, 0, 1);
                                        framecap = framesz;
                                }
                                *(void**)frame = f->arg;
diff --git a/test/fixedbugs/issue5348.go b/test/fixedbugs/issue5348.go
new file mode 100644 (file)
index 0000000..94c3d5d
--- /dev/null
@@ -0,0 +1,37 @@
+// run
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 5348: finalizers keep data live for a surprising amount of time
+
+package main
+
+import (
+       "runtime"
+)
+
+type T struct {
+       S *string
+}
+
+func newString(s string) *string {
+       return &s
+}
+
+var c = make(chan int)
+
+func foo() {
+       t := &T{S: newString("foo")}
+       runtime.SetFinalizer(t, func(p *T) { c <- 0 })
+       runtime.SetFinalizer(t.S, func(p *string) { c <- 0 })
+}
+
+func main() {
+       foo()
+       runtime.GC()
+       <-c
+       runtime.GC()
+       <-c
+}