From 94bdf13497f8a72673d71cc4d4c1a6e05a35b2dc Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 8 Oct 2014 00:03:50 -0400 Subject: [PATCH] runtime: clear Defer.fn before removing from the G.defer list Should fix the remaining 'invalid heap pointer' build failures. TBR=khr CC=golang-codereviews https://golang.org/cl/152360043 --- src/runtime/panic.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/runtime/panic.go b/src/runtime/panic.go index 58b14b09e3..685ff5ca0b 100644 --- a/src/runtime/panic.go +++ b/src/runtime/panic.go @@ -191,6 +191,9 @@ func freedefer(d *_defer) { if d._panic != nil { freedeferpanic() } + if d.fn != nil { + freedeferfn() + } sc := deferclass(uintptr(d.siz)) if sc < uintptr(len(p{}.deferpool)) { mp := acquirem() @@ -209,6 +212,11 @@ func freedeferpanic() { gothrow("freedefer with d._panic != nil") } +func freedeferfn() { + // fn must be cleared before d is unlinked from gp. + gothrow("freedefer with d.fn != nil") +} + // Run a deferred function if there is one. // The compiler inserts a call to this at the end of any // function which calls defer. @@ -241,6 +249,7 @@ func deferreturn(arg0 uintptr) { mp := acquirem() memmove(unsafe.Pointer(argp), deferArgs(d), uintptr(d.siz)) fn := d.fn + d.fn = nil gp._defer = d.link freedefer(d) releasem(mp) @@ -270,6 +279,7 @@ func Goexit() { d._panic.aborted = true d._panic = nil } + d.fn = nil gp._defer = d.link freedefer(d) continue @@ -280,6 +290,7 @@ func Goexit() { gothrow("bad defer entry in Goexit") } d._panic = nil + d.fn = nil gp._defer = d.link freedefer(d) // Note: we ignore recovers here because Goexit isn't a panic @@ -356,6 +367,7 @@ func gopanic(e interface{}) { d._panic.aborted = true } d._panic = nil + d.fn = nil gp._defer = d.link freedefer(d) continue @@ -380,6 +392,7 @@ func gopanic(e interface{}) { gothrow("bad defer entry in panic") } d._panic = nil + d.fn = nil gp._defer = d.link // trigger shrinkage to test stack copy. See stack_test.go:TestStackPanic -- 2.50.0