diff options
author | Keith Randall <khr@golang.org> | 2014-05-27 16:26:08 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2014-05-27 16:26:08 -0700 |
commit | 3d1c3e1e262d8f6d7ad2be52af7d226a6fb88ccf (patch) | |
tree | 156603f542979eb5db191c3a2e99eaabd743064a | |
parent | bd401baef2349e41d99280557bd5d709be78c894 (diff) | |
download | go-3d1c3e1e262d8f6d7ad2be52af7d226a6fb88ccf.tar.gz go-3d1c3e1e262d8f6d7ad2be52af7d226a6fb88ccf.zip |
runtime: stack copier should handle nil defers without faulting.
fixes #8047
LGTM=rsc
R=golang-codereviews, rsc
CC=golang-codereviews
https://golang.org/cl/101800043
-rw-r--r-- | src/pkg/runtime/stack.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/src/pkg/runtime/stack.c b/src/pkg/runtime/stack.c index d265d4b500..a5e0f87a46 100644 --- a/src/pkg/runtime/stack.c +++ b/src/pkg/runtime/stack.c @@ -344,6 +344,8 @@ copyabletopsegment(G *gp) if(d->argp < cinfo.stk || cinfo.base <= d->argp) break; // a defer for the next segment fn = d->fn; + if(fn == nil) // See issue 8047 + continue; f = runtime·findfunc((uintptr)fn->fn); if(f == nil) return -1; @@ -552,13 +554,19 @@ adjustdefers(G *gp, AdjustInfo *adjinfo) } if(d->argp < adjinfo->oldstk || adjinfo->oldbase <= d->argp) break; // a defer for the next segment - f = runtime·findfunc((uintptr)d->fn->fn); + fn = d->fn; + if(fn == nil) { + // Defer of nil function. It will panic when run, and there + // aren't any args to adjust. See issue 8047. + d->argp += adjinfo->delta; + continue; + } + f = runtime·findfunc((uintptr)fn->fn); if(f == nil) runtime·throw("can't adjust unknown defer"); if(StackDebug >= 4) runtime·printf(" checking defer %s\n", runtime·funcname(f)); // Defer's FuncVal might be on the stack - fn = d->fn; if(adjinfo->oldstk <= (byte*)fn && (byte*)fn < adjinfo->oldbase) { if(StackDebug >= 3) runtime·printf(" adjust defer fn %s\n", runtime·funcname(f)); |