diff options
| author | Russ Cox <rsc@golang.org> | 2013-07-18 12:26:47 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2013-07-18 12:26:47 -0400 |
| commit | ef12bbfc9ddbb168fcd2ab0ad0bd364e40a1ab7f (patch) | |
| tree | e27bce91a05d14e669fac7203d0258ef1f64cd07 /src | |
| parent | 8166b2da192919679cd4583c4edb34becbe36e8c (diff) | |
| download | go-ef12bbfc9ddbb168fcd2ab0ad0bd364e40a1ab7f.tar.xz | |
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/pkg/runtime/panic.c | 9 |
1 files changed, 9 insertions, 0 deletions
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); } |
