From: Dmitriy Vyukov Date: Mon, 19 Aug 2013 19:06:46 +0000 (+0400) Subject: runtime: do not preempt race calls X-Git-Tag: go1.2rc2~491 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=d017f578d01fa608d5ed40e343d0ffaf5fc0d476;p=gostls13.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 --- diff --git a/src/pkg/runtime/race.c b/src/pkg/runtime/race.c index 83fa21d4e3..6ee55beff4 100644 --- a/src/pkg/runtime/race.c +++ b/src/pkg/runtime/race.c @@ -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; }