runtime: in doscanstackswitch, set gp->m before gogo

This is following CL 156038. doscanstackswitch uses the same
    mechanism of switching goroutines as getTraceback, and so has
    the same problem as described in issue golang/go#29448. This CL
    applies the same fix.
    
    Reviewed-on: https://go-review.googlesource.com/c/156697

From-SVN: r267661
This commit is contained in:
Ian Lance Taylor 2019-01-07 22:07:26 +00:00
parent fdcef314bc
commit 33a5d8ccb5
2 changed files with 8 additions and 7 deletions

View File

@ -1,4 +1,4 @@
c8a9bccbc524381d150c84907a61ac257c1b07cc 085ef4556ec810a5a9c422e7b86d98441dc92e86
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.

View File

@ -482,9 +482,14 @@ void doscanstackswitch(G*, G*) __asm__(GOSYM_PREFIX "runtime.doscanstackswitch")
void void
doscanstackswitch(G* me, G* gp) doscanstackswitch(G* me, G* gp)
{ {
M* holdm;
__go_assert(me->entry == nil); __go_assert(me->entry == nil);
me->fromgogo = false; me->fromgogo = false;
holdm = gp->m;
gp->m = me->m;
#ifdef USING_SPLIT_STACK #ifdef USING_SPLIT_STACK
__splitstack_getcontext((void*)(&me->stackcontext[0])); __splitstack_getcontext((void*)(&me->stackcontext[0]));
#endif #endif
@ -507,6 +512,8 @@ doscanstackswitch(G* me, G* gp)
if (gp->scang != 0) if (gp->scang != 0)
runtime_gogo(gp); runtime_gogo(gp);
gp->m = holdm;
} }
// Do a stack scan, then switch back to the g that triggers this scan. // Do a stack scan, then switch back to the g that triggers this scan.
@ -515,21 +522,15 @@ static void
gscanstack(G *gp) gscanstack(G *gp)
{ {
G *oldg, *oldcurg; G *oldg, *oldcurg;
M* holdm;
oldg = (G*)gp->scang; oldg = (G*)gp->scang;
oldcurg = oldg->m->curg; oldcurg = oldg->m->curg;
holdm = gp->m;
if(holdm != nil && holdm != g->m)
runtime_throw("gscanstack: m is not nil");
oldg->m->curg = gp; oldg->m->curg = gp;
gp->m = oldg->m;
gp->scang = 0; gp->scang = 0;
doscanstack(gp, (void*)gp->scangcw); doscanstack(gp, (void*)gp->scangcw);
gp->scangcw = 0; gp->scangcw = 0;
gp->m = holdm;
oldg->m->curg = oldcurg; oldg->m->curg = oldcurg;
runtime_gogo(oldg); runtime_gogo(oldg);
} }