Commit 94bdf134 authored by Russ Cox's avatar Russ Cox

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
parent f950a14b
...@@ -191,6 +191,9 @@ func freedefer(d *_defer) { ...@@ -191,6 +191,9 @@ func freedefer(d *_defer) {
if d._panic != nil { if d._panic != nil {
freedeferpanic() freedeferpanic()
} }
if d.fn != nil {
freedeferfn()
}
sc := deferclass(uintptr(d.siz)) sc := deferclass(uintptr(d.siz))
if sc < uintptr(len(p{}.deferpool)) { if sc < uintptr(len(p{}.deferpool)) {
mp := acquirem() mp := acquirem()
...@@ -209,6 +212,11 @@ func freedeferpanic() { ...@@ -209,6 +212,11 @@ func freedeferpanic() {
gothrow("freedefer with d._panic != nil") 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. // Run a deferred function if there is one.
// The compiler inserts a call to this at the end of any // The compiler inserts a call to this at the end of any
// function which calls defer. // function which calls defer.
...@@ -241,6 +249,7 @@ func deferreturn(arg0 uintptr) { ...@@ -241,6 +249,7 @@ func deferreturn(arg0 uintptr) {
mp := acquirem() mp := acquirem()
memmove(unsafe.Pointer(argp), deferArgs(d), uintptr(d.siz)) memmove(unsafe.Pointer(argp), deferArgs(d), uintptr(d.siz))
fn := d.fn fn := d.fn
d.fn = nil
gp._defer = d.link gp._defer = d.link
freedefer(d) freedefer(d)
releasem(mp) releasem(mp)
...@@ -270,6 +279,7 @@ func Goexit() { ...@@ -270,6 +279,7 @@ func Goexit() {
d._panic.aborted = true d._panic.aborted = true
d._panic = nil d._panic = nil
} }
d.fn = nil
gp._defer = d.link gp._defer = d.link
freedefer(d) freedefer(d)
continue continue
...@@ -280,6 +290,7 @@ func Goexit() { ...@@ -280,6 +290,7 @@ func Goexit() {
gothrow("bad defer entry in Goexit") gothrow("bad defer entry in Goexit")
} }
d._panic = nil d._panic = nil
d.fn = nil
gp._defer = d.link gp._defer = d.link
freedefer(d) freedefer(d)
// Note: we ignore recovers here because Goexit isn't a panic // Note: we ignore recovers here because Goexit isn't a panic
...@@ -356,6 +367,7 @@ func gopanic(e interface{}) { ...@@ -356,6 +367,7 @@ func gopanic(e interface{}) {
d._panic.aborted = true d._panic.aborted = true
} }
d._panic = nil d._panic = nil
d.fn = nil
gp._defer = d.link gp._defer = d.link
freedefer(d) freedefer(d)
continue continue
...@@ -380,6 +392,7 @@ func gopanic(e interface{}) { ...@@ -380,6 +392,7 @@ func gopanic(e interface{}) {
gothrow("bad defer entry in panic") gothrow("bad defer entry in panic")
} }
d._panic = nil d._panic = nil
d.fn = nil
gp._defer = d.link gp._defer = d.link
// trigger shrinkage to test stack copy. See stack_test.go:TestStackPanic // trigger shrinkage to test stack copy. See stack_test.go:TestStackPanic
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment