byte *p;
Eface i;
+ // raceinit must be the first call to race detector.
+ // In particular, it must be done before mallocinit below calls racemapshadow.
+ if(raceenabled)
+ g->racectx = runtime·raceinit();
+
runtime·sched.maxmcount = 10000;
runtime·precisestack = true; // haveexperiment("precisestack");
runtime·copystack = false;
mstats.enablegc = 1;
-
- if(raceenabled)
- g->racectx = runtime·raceinit();
}
extern void main·init(void);
// with up to 4 uintptr arguments.
void runtime·racecall(void(*f)(void), ...);
+// checks if the address has shadow (i.e. heap or data/bss)
+static bool
+isvalidaddr(uintptr addr)
+{
+ if(addr >= runtime·racearenastart && addr < runtime·racearenaend)
+ return true;
+ if(addr >= (uintptr)noptrdata && addr < (uintptr)enoptrbss)
+ return true;
+ return false;
+}
+
uintptr
runtime·raceinit(void)
{
void
runtime·raceacquireg(G *gp, void *addr)
{
- if(g->raceignore)
+ if(g->raceignore || !isvalidaddr((uintptr)addr))
return;
runtime·racecall(__tsan_acquire, gp->racectx, addr);
}
void
runtime·racerelease(void *addr)
{
+ if(g->raceignore || !isvalidaddr((uintptr)addr))
+ return;
runtime·racereleaseg(g, addr);
}
void
runtime·racereleaseg(G *gp, void *addr)
{
- if(g->raceignore)
+ if(g->raceignore || !isvalidaddr((uintptr)addr))
return;
runtime·racecall(__tsan_release, gp->racectx, addr);
}
void
runtime·racereleasemergeg(G *gp, void *addr)
{
- if(g->raceignore)
+ if(g->raceignore || !isvalidaddr((uintptr)addr))
return;
runtime·racecall(__tsan_release_merge, gp->racectx, addr);
}