tsan: use stack depot for goroutine creation stacks (as C++ threads do)

llvm-svn: 204326
This commit is contained in:
Dmitry Vyukov 2014-03-20 10:19:02 +00:00
parent 87d13e5ec1
commit 6e2557769c
4 changed files with 6 additions and 20 deletions

View File

@ -485,11 +485,7 @@ class ThreadContext : public ThreadContextBase {
explicit ThreadContext(int tid); explicit ThreadContext(int tid);
~ThreadContext(); ~ThreadContext();
ThreadState *thr; ThreadState *thr;
#ifdef TSAN_GO
StackTrace creation_stack;
#else
u32 creation_stack_id; u32 creation_stack_id;
#endif
SyncClock sync; SyncClock sync;
// Epoch at which the thread had started. // Epoch at which the thread had started.
// If we see an event from the thread stamped by an older epoch, // If we see an event from the thread stamped by an older epoch,

View File

@ -104,8 +104,9 @@ static void StackStripMain(ReportStack *stack) {
#endif #endif
} }
#ifndef TSAN_GO
ReportStack *SymbolizeStackId(u32 stack_id) { ReportStack *SymbolizeStackId(u32 stack_id) {
if (stack_id == 0)
return 0;
uptr ssz = 0; uptr ssz = 0;
const uptr *stack = StackDepotGet(stack_id, &ssz); const uptr *stack = StackDepotGet(stack_id, &ssz);
if (stack == 0) if (stack == 0)
@ -114,7 +115,6 @@ ReportStack *SymbolizeStackId(u32 stack_id) {
trace.Init(stack, ssz); trace.Init(stack, ssz);
return SymbolizeStack(trace); return SymbolizeStack(trace);
} }
#endif
static ReportStack *SymbolizeStack(const StackTrace& trace) { static ReportStack *SymbolizeStack(const StackTrace& trace) {
if (trace.IsEmpty()) if (trace.IsEmpty())
@ -201,11 +201,7 @@ void ScopedReport::AddThread(const ThreadContext *tctx) {
rt->name = internal_strdup(tctx->name); rt->name = internal_strdup(tctx->name);
rt->parent_tid = tctx->parent_tid; rt->parent_tid = tctx->parent_tid;
rt->stack = 0; rt->stack = 0;
#ifdef TSAN_GO
rt->stack = SymbolizeStack(tctx->creation_stack);
#else
rt->stack = SymbolizeStackId(tctx->creation_stack_id); rt->stack = SymbolizeStackId(tctx->creation_stack_id);
#endif
} }
#ifndef TSAN_GO #ifndef TSAN_GO
@ -266,10 +262,7 @@ void ScopedReport::AddMutex(const SyncVar *s) {
rm->id = s->uid; rm->id = s->uid;
rm->addr = s->addr; rm->addr = s->addr;
rm->destroyed = false; rm->destroyed = false;
rm->stack = 0;
#ifndef TSAN_GO
rm->stack = SymbolizeStackId(s->creation_stack_id); rm->stack = SymbolizeStackId(s->creation_stack_id);
#endif
} }
u64 ScopedReport::AddMutex(u64 id) { u64 ScopedReport::AddMutex(u64 id) {

View File

@ -59,11 +59,7 @@ void ThreadContext::OnCreated(void *arg) {
// Can't increment epoch w/o writing to the trace as well. // Can't increment epoch w/o writing to the trace as well.
TraceAddEvent(args->thr, args->thr->fast_state, EventTypeMop, 0); TraceAddEvent(args->thr, args->thr->fast_state, EventTypeMop, 0);
ReleaseImpl(args->thr, 0, &sync); ReleaseImpl(args->thr, 0, &sync);
#ifdef TSAN_GO
creation_stack.ObtainCurrent(args->thr, args->pc);
#else
creation_stack_id = CurrentStackId(args->thr, args->pc); creation_stack_id = CurrentStackId(args->thr, args->pc);
#endif
if (reuse_count == 0) if (reuse_count == 0)
StatInc(args->thr, StatThreadMaxTid); StatInc(args->thr, StatThreadMaxTid);
} }

View File

@ -23,6 +23,7 @@ SyncVar::SyncVar(uptr addr, u64 uid)
: mtx(MutexTypeSyncVar, StatMtxSyncVar) : mtx(MutexTypeSyncVar, StatMtxSyncVar)
, addr(addr) , addr(addr)
, uid(uid) , uid(uid)
, creation_stack_id()
, owner_tid(kInvalidTid) , owner_tid(kInvalidTid)
, last_lock() , last_lock()
, recursion() , recursion()
@ -64,9 +65,9 @@ SyncVar* SyncTab::Create(ThreadState *thr, uptr pc, uptr addr) {
void *mem = internal_alloc(MBlockSync, sizeof(SyncVar)); void *mem = internal_alloc(MBlockSync, sizeof(SyncVar));
const u64 uid = atomic_fetch_add(&uid_gen_, 1, memory_order_relaxed); const u64 uid = atomic_fetch_add(&uid_gen_, 1, memory_order_relaxed);
SyncVar *res = new(mem) SyncVar(addr, uid); SyncVar *res = new(mem) SyncVar(addr, uid);
#ifndef TSAN_GO res->creation_stack_id = 0;
res->creation_stack_id = CurrentStackId(thr, pc); if (!kGoMode) // Go does not use them
#endif res->creation_stack_id = CurrentStackId(thr, pc);
if (flags()->detect_deadlocks) if (flags()->detect_deadlocks)
DDMutexInit(thr, pc, res); DDMutexInit(thr, pc, res);
return res; return res;