mirror of https://github.com/golang/go.git
runtime: do not preempt race calls
In the crash stack trace race cgocall() calls endcgo(), this means that m->racecall is wrong. Indeed this can happen is a goroutine is rescheduled to another M during race call. Disable preemption for race calls. Fixes #6155. R=golang-dev, rsc, cshapiro CC=golang-dev https://golang.org/cl/12866045
This commit is contained in:
parent
21ea5103a4
commit
d017f578d0
|
|
@ -34,17 +34,23 @@ extern byte enoptrbss[];
|
|||
|
||||
static bool onstack(uintptr argp);
|
||||
|
||||
// We set m->racecall around all calls into race library to trigger fast path in cgocall.
|
||||
// Also we increment m->locks to disable preemption and potential rescheduling
|
||||
// to ensure that we reset m->racecall on the correct m.
|
||||
|
||||
uintptr
|
||||
runtime·raceinit(void)
|
||||
{
|
||||
uintptr racectx, start, size;
|
||||
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·Initialize(&racectx);
|
||||
// Round data segment to page boundaries, because it's used in mmap().
|
||||
start = (uintptr)noptrdata & ~(PageSize-1);
|
||||
size = ROUND((uintptr)enoptrbss - start, PageSize);
|
||||
runtime∕race·MapShadow((void*)start, size);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
return racectx;
|
||||
}
|
||||
|
|
@ -53,7 +59,9 @@ void
|
|||
runtime·racefini(void)
|
||||
{
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·Finalize();
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +69,9 @@ void
|
|||
runtime·racemapshadow(void *addr, uintptr size)
|
||||
{
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·MapShadow(addr, size);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +83,9 @@ runtime·racewrite(uintptr addr)
|
|||
{
|
||||
if(!onstack(addr)) {
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·Write(g->racectx, (void*)addr, runtime·getcallerpc(&addr));
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -84,7 +96,9 @@ runtime·racewriterange(uintptr addr, uintptr sz)
|
|||
{
|
||||
if(!onstack(addr)) {
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·WriteRange(g->racectx, (void*)addr, sz, runtime·getcallerpc(&addr));
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -97,7 +111,9 @@ runtime·raceread(uintptr addr)
|
|||
{
|
||||
if(!onstack(addr)) {
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·Read(g->racectx, (void*)addr, runtime·getcallerpc(&addr));
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +124,9 @@ runtime·racereadrange(uintptr addr, uintptr sz)
|
|||
{
|
||||
if(!onstack(addr)) {
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·ReadRange(g->racectx, (void*)addr, sz, runtime·getcallerpc(&addr));
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -124,7 +142,9 @@ runtime·racefuncenter1(uintptr pc)
|
|||
runtime·callers(2, &pc, 1);
|
||||
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·FuncEnter(g->racectx, (void*)pc);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +154,9 @@ void
|
|||
runtime·racefuncexit(void)
|
||||
{
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·FuncExit(g->racectx);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +167,9 @@ runtime·racemalloc(void *p, uintptr sz)
|
|||
if(m->curg == nil)
|
||||
return;
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·Malloc(m->curg->racectx, p, sz, /* unused pc */ 0);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
|
|
@ -153,7 +177,9 @@ void
|
|||
runtime·racefree(void *p)
|
||||
{
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·Free(p);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +189,9 @@ runtime·racegostart(void *pc)
|
|||
uintptr racectx;
|
||||
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·GoStart(g->racectx, &racectx, pc);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
return racectx;
|
||||
}
|
||||
|
|
@ -172,7 +200,9 @@ void
|
|||
runtime·racegoend(void)
|
||||
{
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·GoEnd(g->racectx);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
|
|
@ -183,6 +213,7 @@ memoryaccess(void *addr, uintptr callpc, uintptr pc, bool write)
|
|||
|
||||
if(!onstack((uintptr)addr)) {
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
racectx = g->racectx;
|
||||
if(callpc) {
|
||||
if(callpc == (uintptr)runtime·lessstack)
|
||||
|
|
@ -195,6 +226,7 @@ memoryaccess(void *addr, uintptr callpc, uintptr pc, bool write)
|
|||
runtime∕race·Read(racectx, addr, (void*)pc);
|
||||
if(callpc)
|
||||
runtime∕race·FuncExit(racectx);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -218,6 +250,7 @@ rangeaccess(void *addr, uintptr size, uintptr callpc, uintptr pc, bool write)
|
|||
|
||||
if(!onstack((uintptr)addr)) {
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
racectx = g->racectx;
|
||||
if(callpc) {
|
||||
if(callpc == (uintptr)runtime·lessstack)
|
||||
|
|
@ -230,6 +263,7 @@ rangeaccess(void *addr, uintptr size, uintptr callpc, uintptr pc, bool write)
|
|||
runtime∕race·ReadRange(racectx, addr, size, (void*)pc);
|
||||
if(callpc)
|
||||
runtime∕race·FuncExit(racectx);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -258,7 +292,9 @@ runtime·raceacquireg(G *gp, void *addr)
|
|||
if(g->raceignore)
|
||||
return;
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·Acquire(gp->racectx, addr);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
|
|
@ -274,7 +310,9 @@ runtime·racereleaseg(G *gp, void *addr)
|
|||
if(g->raceignore)
|
||||
return;
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·Release(gp->racectx, addr);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
|
|
@ -290,7 +328,9 @@ runtime·racereleasemergeg(G *gp, void *addr)
|
|||
if(g->raceignore)
|
||||
return;
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·ReleaseMerge(gp->racectx, addr);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
|
|
@ -298,7 +338,9 @@ void
|
|||
runtime·racefingo(void)
|
||||
{
|
||||
m->racecall = true;
|
||||
m->locks++;
|
||||
runtime∕race·FinalizerGoroutine(g->racectx);
|
||||
m->locks--;
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue