aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Ziak <0xe2.0x9a.0x9b@gmail.com>2013-04-25 13:39:09 +0200
committerJan Ziak <0xe2.0x9a.0x9b@gmail.com>2013-04-25 13:39:09 +0200
commite9bbe3a8da9043e13b74ec4427608364b068bed7 (patch)
tree913824748b82d7633ca82e301aa1d55e1196d582
parent2bd17bca0776ff8bb661259d2ed6de6a325ac197 (diff)
downloadgo-e9bbe3a8da9043e13b74ec4427608364b068bed7.tar.gz
go-e9bbe3a8da9043e13b74ec4427608364b068bed7.zip
runtime: prevent the GC from seeing the content of a frame in runfinq()
Fixes #5348. R=golang-dev, dvyukov CC=golang-dev https://golang.org/cl/8954044
-rw-r--r--src/pkg/runtime/mgc0.c2
-rw-r--r--test/fixedbugs/issue5348.go37
2 files changed, 38 insertions, 1 deletions
diff --git a/src/pkg/runtime/mgc0.c b/src/pkg/runtime/mgc0.c
index f9dbdbb4a1..6369da2720 100644
--- a/src/pkg/runtime/mgc0.c
+++ b/src/pkg/runtime/mgc0.c
@@ -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
index 0000000000..94c3d5d15f
--- /dev/null
+++ b/test/fixedbugs/issue5348.go
@@ -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
+}