On Mon, Jan 7, 2019 at 12:12 PM Ian Lance Taylor <i...@golang.org> wrote:
>
> This libgo patch by Cherry Zhang moves setting p->m from gtraceback to
> getTraceback.  Currently, when collecting a traceback for another
> goroutine, getTraceback calls gogo(gp) switching to gp, which will
> resume in mcall, which will call gtraceback, which will set up gp->m.
> There is a gap between setting the current running g to gp and setting
> gp->m. If a profiling signal arrives in between, sigtramp will see a
> non-nil gp with a nil m, and will seg fault.  This patch fixes this by
> setting up gp->m first.  This fixes https://golang.org/issue/29448.
> Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
> to mainline.

And here is a follow up patch by Cherry Zhang to make the same fix in
doscanstackswitch.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE     (revision 267660)
+++ gcc/go/gofrontend/MERGE     (working copy)
@@ -1,4 +1,4 @@
-c8a9bccbc524381d150c84907a61ac257c1b07cc
+085ef4556ec810a5a9c422e7b86d98441dc92e86
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: libgo/runtime/proc.c
===================================================================
--- libgo/runtime/proc.c        (revision 267658)
+++ libgo/runtime/proc.c        (working copy)
@@ -482,9 +482,14 @@ void doscanstackswitch(G*, G*) __asm__(G
 void
 doscanstackswitch(G* me, G* gp)
 {
+       M* holdm;
+
        __go_assert(me->entry == nil);
        me->fromgogo = false;
 
+       holdm = gp->m;
+       gp->m = me->m;
+
 #ifdef USING_SPLIT_STACK
        __splitstack_getcontext((void*)(&me->stackcontext[0]));
 #endif
@@ -507,6 +512,8 @@ doscanstackswitch(G* me, G* gp)
 
        if (gp->scang != 0)
                runtime_gogo(gp);
+
+       gp->m = holdm;
 }
 
 // Do a stack scan, then switch back to the g that triggers this scan.
@@ -515,21 +522,15 @@ static void
 gscanstack(G *gp)
 {
        G *oldg, *oldcurg;
-       M* holdm;
 
        oldg = (G*)gp->scang;
        oldcurg = oldg->m->curg;
-       holdm = gp->m;
-       if(holdm != nil && holdm != g->m)
-               runtime_throw("gscanstack: m is not nil");
        oldg->m->curg = gp;
-       gp->m = oldg->m;
        gp->scang = 0;
 
        doscanstack(gp, (void*)gp->scangcw);
 
        gp->scangcw = 0;
-       gp->m = holdm;
        oldg->m->curg = oldcurg;
        runtime_gogo(oldg);
 }

Reply via email to