Another dangling stack pointer in a cached structure.
Same as SudoG.elem and SudoG.selectdone.
Definitely a fix, and the new test in freedefer makes the
crash reproducible, but probably not a complete fix.
I have seen one dangling pointer in a Defer.panic even
after this fix; I cannot see where it could be coming from.
I think this will fix the solaris build.
I do not think this will fix the occasional failure on the darwin build.
TBR=khr
R=khr
CC=golang-codereviews
https://golang.org/cl/
155080043
g->m->scalararg[1] = 0;
d = runtime·newdefer(siz);
+ if(d->panic != nil)
+ runtime·throw("deferproc: d->panic != nil after newdefer");
d->fn = fn;
d->pc = callerpc;
d->argp = argp;
// The defer cannot be used after this call.
//go:nosplit
func freedefer(d *_defer) {
+ if d._panic != nil {
+ // _panic must be cleared before d is unlinked from gp.
+ gothrow("freedefer with d._panic != nil")
+ }
sc := deferclass(uintptr(d.siz))
if sc < uintptr(len(p{}.deferpool)) {
mp := acquirem()
if d.started {
if d._panic != nil {
d._panic.aborted = true
+ d._panic = nil
}
gp._defer = d.link
freedefer(d)
if gp._defer != d {
gothrow("bad defer entry in Goexit")
}
+ d._panic = nil
gp._defer = d.link
freedefer(d)
// Note: we ignore recovers here because Goexit isn't a panic
if d._panic != nil {
d._panic.aborted = true
}
+ d._panic = nil
gp._defer = d.link
freedefer(d)
continue
if gp._defer != d {
gothrow("bad defer entry in panic")
}
+ d._panic = nil
gp._defer = d.link
// trigger shrinkage to test stack copy. See stack_test.go:TestStackPanic