1
0
mirror of https://github.com/golang/go synced 2024-11-23 06:00:08 -07:00

fix garbage collection race: save stack trace

when changing process state to Gsyscall, not after.

R=r
DELTA=8  (4 added, 3 deleted, 1 changed)
OCL=30320
CL=30325
This commit is contained in:
Russ Cox 2009-06-15 21:30:53 -07:00
parent acaba18bba
commit 36835c7a47

View File

@ -447,7 +447,7 @@ scheduler(void)
if(debug > 1) { if(debug > 1) {
lock(&debuglock); lock(&debuglock);
printf("m%d run g%d at %p\n", m->id, gp->goid, gp->sched.PC); printf("m%d run g%d at %p\n", m->id, gp->goid, gp->sched.PC);
traceback(gp->sched.PC, gp->sched.SP+8, gp); traceback(gp->sched.PC, gp->sched.SP+sizeof(uintptr), gp);
unlock(&debuglock); unlock(&debuglock);
} }
m->curg = gp; m->curg = gp;
@ -488,6 +488,10 @@ sys·entersyscall(uint64 callerpc, int64 trap)
} }
lock(&sched); lock(&sched);
g->status = Gsyscall; g->status = Gsyscall;
// Leave SP around for gc and traceback.
// Do before notewakeup so that gc
// never sees Gsyscall with wrong stack.
gosave(&g->sched);
sched.mcpu--; sched.mcpu--;
sched.msyscall++; sched.msyscall++;
if(sched.gwait != 0) if(sched.gwait != 0)
@ -497,8 +501,6 @@ sys·entersyscall(uint64 callerpc, int64 trap)
notewakeup(&sched.stopped); notewakeup(&sched.stopped);
} }
unlock(&sched); unlock(&sched);
// leave SP around for gc and traceback
gosave(&g->sched);
} }
// The goroutine g exited its system call. // The goroutine g exited its system call.
@ -823,7 +825,6 @@ sys·deferreturn(uintptr arg0)
{ {
Defer *d; Defer *d;
byte *sp, *fn; byte *sp, *fn;
uintptr *caller;
d = g->defer; d = g->defer;
if(d == nil) if(d == nil)