]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: disable preemption during deferreturn
authorRuss Cox <rsc@golang.org>
Thu, 18 Jul 2013 16:26:47 +0000 (12:26 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 18 Jul 2013 16:26:47 +0000 (12:26 -0400)
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

src/pkg/runtime/panic.c

index 120f7706e72cdf84b0112fa77fd77354fa75212c..5692c537a0a3530dacd82b58f64a43b530f3e0ef 100644 (file)
@@ -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);
 }