mirror of https://github.com/golang/go.git
runtime: fix deadlock detector false negative
The issue was that scvg is assigned *after* the scavenger goroutine is started, so when the scavenger calls entersyscall() the g==scvg check can fail. Fixes #5025. R=golang-dev, iant CC=golang-dev https://golang.org/cl/7629045
This commit is contained in:
parent
7f070af515
commit
6ee739d7e9
|
|
@ -409,6 +409,9 @@ runtime·MHeap_Scavenger(void)
|
||||||
bool trace;
|
bool trace;
|
||||||
Note note, *notep;
|
Note note, *notep;
|
||||||
|
|
||||||
|
g->issystem = true;
|
||||||
|
g->isbackground = true;
|
||||||
|
|
||||||
// If we go two minutes without a garbage collection, force one to run.
|
// If we go two minutes without a garbage collection, force one to run.
|
||||||
forcegc = 2*60*1e9;
|
forcegc = 2*60*1e9;
|
||||||
// If a span goes unused for 5 minutes after a garbage collection,
|
// If a span goes unused for 5 minutes after a garbage collection,
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,6 @@ M* runtime·extram;
|
||||||
int8* runtime·goos;
|
int8* runtime·goos;
|
||||||
int32 runtime·ncpu;
|
int32 runtime·ncpu;
|
||||||
static int32 newprocs;
|
static int32 newprocs;
|
||||||
// Keep trace of scavenger's goroutine for deadlock detection.
|
|
||||||
static G *scvg;
|
|
||||||
|
|
||||||
void runtime·mstart(void);
|
void runtime·mstart(void);
|
||||||
static void runqput(P*, G*);
|
static void runqput(P*, G*);
|
||||||
|
|
@ -174,8 +172,7 @@ runtime·main(void)
|
||||||
runtime·lockOSThread();
|
runtime·lockOSThread();
|
||||||
if(m != &runtime·m0)
|
if(m != &runtime·m0)
|
||||||
runtime·throw("runtime·main not on m0");
|
runtime·throw("runtime·main not on m0");
|
||||||
scvg = runtime·newproc1(&scavenger, nil, 0, 0, runtime·main);
|
runtime·newproc1(&scavenger, nil, 0, 0, runtime·main);
|
||||||
scvg->issystem = true;
|
|
||||||
main·init();
|
main·init();
|
||||||
runtime·unlockOSThread();
|
runtime·unlockOSThread();
|
||||||
|
|
||||||
|
|
@ -1265,7 +1262,7 @@ void
|
||||||
|
|
||||||
p = releasep();
|
p = releasep();
|
||||||
handoffp(p);
|
handoffp(p);
|
||||||
if(g == scvg) // do not consider blocked scavenger for deadlock detection
|
if(g->isbackground) // do not consider blocked scavenger for deadlock detection
|
||||||
inclocked(1);
|
inclocked(1);
|
||||||
runtime·gosave(&g->sched); // re-save for traceback
|
runtime·gosave(&g->sched); // re-save for traceback
|
||||||
}
|
}
|
||||||
|
|
@ -1297,7 +1294,7 @@ runtime·exitsyscall(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(g == scvg) // do not consider blocked scavenger for deadlock detection
|
if(g->isbackground) // do not consider blocked scavenger for deadlock detection
|
||||||
inclocked(-1);
|
inclocked(-1);
|
||||||
// Try to get any other idle P.
|
// Try to get any other idle P.
|
||||||
m->p = nil;
|
m->p = nil;
|
||||||
|
|
@ -1899,7 +1896,7 @@ checkdead(void)
|
||||||
}
|
}
|
||||||
grunning = 0;
|
grunning = 0;
|
||||||
for(gp = runtime·allg; gp; gp = gp->alllink) {
|
for(gp = runtime·allg; gp; gp = gp->alllink) {
|
||||||
if(gp == scvg)
|
if(gp->isbackground)
|
||||||
continue;
|
continue;
|
||||||
s = gp->status;
|
s = gp->status;
|
||||||
if(s == Gwaiting)
|
if(s == Gwaiting)
|
||||||
|
|
|
||||||
|
|
@ -235,8 +235,9 @@ struct G
|
||||||
int8* waitreason; // if status==Gwaiting
|
int8* waitreason; // if status==Gwaiting
|
||||||
G* schedlink;
|
G* schedlink;
|
||||||
bool ispanic;
|
bool ispanic;
|
||||||
bool issystem;
|
bool issystem; // do not output in stack dump
|
||||||
int8 raceignore; // ignore race detection events
|
bool isbackground; // ignore in deadlock detector
|
||||||
|
int8 raceignore; // ignore race detection events
|
||||||
M* m; // for debuggers, but offset not hard-coded
|
M* m; // for debuggers, but offset not hard-coded
|
||||||
M* lockedm;
|
M* lockedm;
|
||||||
int32 sig;
|
int32 sig;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue