aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/testdata
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-02-27 12:34:20 -0500
committerCherry Zhang <cherryyz@google.com>2019-03-01 16:21:29 +0000
commit4f4c2a79d4f952b96d58aec2926b4c894245071b (patch)
tree41c5b7f6bb790fa44f6d09a78725ba8590400f86 /src/runtime/testdata
parentc04e47f82159f1010d7403276b3dff5ab836fd00 (diff)
downloadgo-4f4c2a79d4f952b96d58aec2926b4c894245071b.tar.xz
runtime: scan defer closure in stack scan
With stack objects, when we scan the stack, it scans defers with tracebackdefers, but it seems to me that tracebackdefers doesn't include the func value itself, which could be a stack allocated closure. Scan it explicitly. Alternatively, we can change tracebackdefers to include the func value, which in turn needs to change the type of stkframe. Fixes #30453. Change-Id: I55a6e43264d6952ab2fa5c638bebb89fdc410e2b Reviewed-on: https://go-review.googlesource.com/c/164118 Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/runtime/testdata')
-rw-r--r--src/runtime/testdata/testprog/gc.go23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/runtime/testdata/testprog/gc.go b/src/runtime/testdata/testprog/gc.go
index fdf08be7e9..ea6604f132 100644
--- a/src/runtime/testdata/testprog/gc.go
+++ b/src/runtime/testdata/testprog/gc.go
@@ -18,6 +18,7 @@ func init() {
register("GCFairness2", GCFairness2)
register("GCSys", GCSys)
register("GCPhys", GCPhys)
+ register("DeferLiveness", DeferLiveness)
}
func GCSys() {
@@ -207,3 +208,25 @@ func GCPhys() {
fmt.Println("OK")
runtime.KeepAlive(saved)
}
+
+// Test that defer closure is correctly scanned when the stack is scanned.
+func DeferLiveness() {
+ var x [10]int
+ escape(&x)
+ fn := func() {
+ if x[0] != 42 {
+ panic("FAIL")
+ }
+ }
+ defer fn()
+
+ x[0] = 42
+ runtime.GC()
+ runtime.GC()
+ runtime.GC()
+}
+
+//go:noinline
+func escape(x interface{}) { sink2 = x; sink2 = nil }
+
+var sink2 interface{}