aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/panic.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-10-08 00:03:50 -0400
committerRuss Cox <rsc@golang.org>2014-10-08 00:03:50 -0400
commit94bdf13497f8a72673d71cc4d4c1a6e05a35b2dc (patch)
tree143b292ede0ace6227f9e51d31bd47c66ce2e186 /src/runtime/panic.go
parentf950a14bb555938cd3878dd59cc447026e1108b9 (diff)
downloadgo-94bdf13497f8a72673d71cc4d4c1a6e05a35b2dc.tar.xz
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
Diffstat (limited to 'src/runtime/panic.go')
-rw-r--r--src/runtime/panic.go13
1 files changed, 13 insertions, 0 deletions
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