Commit ef12bbfc authored by Russ Cox's avatar Russ Cox

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
parent 8166b2da
...@@ -175,10 +175,19 @@ runtime·deferreturn(uintptr arg0, ...) ...@@ -175,10 +175,19 @@ runtime·deferreturn(uintptr arg0, ...)
argp = (byte*)&arg0; argp = (byte*)&arg0;
if(d->argp != argp) if(d->argp != argp)
return; 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); runtime·memmove(argp, d->args, d->siz);
fn = d->fn; fn = d->fn;
popdefer(); popdefer();
freedefer(d); freedefer(d);
m->locks--;
if(m->locks == 0 && g->preempt)
g->stackguard0 = StackPreempt;
runtime·jmpdefer(fn, argp); runtime·jmpdefer(fn, argp);
} }
......
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