From: Russ Cox Date: Thu, 18 Jul 2013 16:26:47 +0000 (-0400) Subject: runtime: disable preemption during deferreturn X-Git-Tag: go1.2rc2~1005 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ef12bbfc9ddbb168fcd2ab0ad0bd364e40a1ab7f;p=gostls13.git runtime: disable preemption during deferreturn Deferreturn is synthesizing a new call frame. It must not be interrupted between copying the args there and fixing up the program counter, or else the stack will be in an inconsistent state, one that will confuse the garbage collector. R=golang-dev, dvyukov CC=golang-dev https://golang.org/cl/11522043 --- diff --git a/src/pkg/runtime/panic.c b/src/pkg/runtime/panic.c index 120f7706e7..5692c537a0 100644 --- a/src/pkg/runtime/panic.c +++ b/src/pkg/runtime/panic.c @@ -175,10 +175,19 @@ runtime·deferreturn(uintptr arg0, ...) argp = (byte*)&arg0; if(d->argp != argp) return; + + // Moving arguments around. + // Do not allow preemption here, because the garbage collector + // won't know the form of the arguments until the jmpdefer can + // flip the PC over to fn. + m->locks++; runtime·memmove(argp, d->args, d->siz); fn = d->fn; popdefer(); freedefer(d); + m->locks--; + if(m->locks == 0 && g->preempt) + g->stackguard0 = StackPreempt; runtime·jmpdefer(fn, argp); }