forked from OSchip/llvm-project
parent
6c7dbf5858
commit
5bfac97ff9
|
|
@ -28,9 +28,7 @@ const int kTidBits = 13;
|
|||
const unsigned kMaxTid = 1 << kTidBits;
|
||||
const unsigned kMaxTidInClock = kMaxTid * 2; // This includes msb 'freed' bit.
|
||||
const int kClkBits = 43;
|
||||
#ifdef TSAN_GO
|
||||
const int kShadowStackSize = 8 * 1024;
|
||||
#else
|
||||
#ifndef TSAN_GO
|
||||
const int kShadowStackSize = 1024;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ enum MBlockType {
|
|||
MBlockScopedBuf,
|
||||
MBlockString,
|
||||
MBlockStackTrace,
|
||||
MBlockShadowStack,
|
||||
MBlockSync,
|
||||
MBlockClock,
|
||||
MBlockThreadContex,
|
||||
|
|
|
|||
|
|
@ -451,14 +451,28 @@ void MemoryRangeFreed(ThreadState *thr, uptr pc, uptr addr, uptr size) {
|
|||
void FuncEntry(ThreadState *thr, uptr pc) {
|
||||
DCHECK_EQ(thr->in_rtl, 0);
|
||||
StatInc(thr, StatFuncEnter);
|
||||
DPrintf2("#%d: tsan::FuncEntry %p\n", (int)thr->fast_state.tid(), (void*)pc);
|
||||
DPrintf2("#%d: FuncEntry %p\n", (int)thr->fast_state.tid(), (void*)pc);
|
||||
thr->fast_state.IncrementEpoch();
|
||||
TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeFuncEnter, pc);
|
||||
|
||||
// Shadow stack maintenance can be replaced with
|
||||
// stack unwinding during trace switch (which presumably must be faster).
|
||||
DCHECK_GE(thr->shadow_stack_pos, &thr->shadow_stack[0]);
|
||||
#ifndef TSAN_GO
|
||||
DCHECK_LT(thr->shadow_stack_pos, &thr->shadow_stack[kShadowStackSize]);
|
||||
#else
|
||||
if (thr->shadow_stack_pos == thr->shadow_stack_end) {
|
||||
const int sz = thr->shadow_stack_end - thr->shadow_stack;
|
||||
const int newsz = 2 * sz;
|
||||
uptr *newstack = (uptr*)internal_alloc(MBlockShadowStack,
|
||||
newsz * sizeof(uptr));
|
||||
internal_memcpy(newstack, thr->shadow_stack, sz * sizeof(uptr));
|
||||
internal_free(thr->shadow_stack);
|
||||
thr->shadow_stack = newstack;
|
||||
thr->shadow_stack_pos = newstack + sz;
|
||||
thr->shadow_stack_end = newstack + newsz;
|
||||
}
|
||||
#endif
|
||||
thr->shadow_stack_pos[0] = pc;
|
||||
thr->shadow_stack_pos++;
|
||||
}
|
||||
|
|
@ -466,12 +480,14 @@ void FuncEntry(ThreadState *thr, uptr pc) {
|
|||
void FuncExit(ThreadState *thr) {
|
||||
DCHECK_EQ(thr->in_rtl, 0);
|
||||
StatInc(thr, StatFuncExit);
|
||||
DPrintf2("#%d: tsan::FuncExit\n", (int)thr->fast_state.tid());
|
||||
DPrintf2("#%d: FuncExit\n", (int)thr->fast_state.tid());
|
||||
thr->fast_state.IncrementEpoch();
|
||||
TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeFuncExit, 0);
|
||||
|
||||
DCHECK_GT(thr->shadow_stack_pos, &thr->shadow_stack[0]);
|
||||
#ifndef TSAN_GO
|
||||
DCHECK_LT(thr->shadow_stack_pos, &thr->shadow_stack[kShadowStackSize]);
|
||||
#endif
|
||||
thr->shadow_stack_pos--;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -228,7 +228,14 @@ struct ThreadState {
|
|||
u64 *racy_shadow_addr;
|
||||
u64 racy_state[2];
|
||||
Trace trace;
|
||||
#ifndef TSAN_GO
|
||||
// C/C++ uses embed shadow stack of fixed size.
|
||||
uptr shadow_stack[kShadowStackSize];
|
||||
#else
|
||||
// Go uses satellite shadow stack with dynamic size.
|
||||
uptr *shadow_stack;
|
||||
uptr *shadow_stack_end;
|
||||
#endif
|
||||
ThreadClock clock;
|
||||
u64 stat[StatCnt];
|
||||
const int tid;
|
||||
|
|
|
|||
|
|
@ -173,6 +173,14 @@ void ThreadStart(ThreadState *thr, int tid) {
|
|||
tctx->epoch1 = (u64)-1;
|
||||
new(thr) ThreadState(CTX(), tid, tctx->epoch0, stk_addr, stk_size,
|
||||
tls_addr, tls_size);
|
||||
#ifdef TSAN_GO
|
||||
// Setup dynamic shadow stack.
|
||||
const int kInitStackSize = 8;
|
||||
thr->shadow_stack = (uptr*)internal_alloc(MBlockShadowStack,
|
||||
kInitStackSize * sizeof(uptr));
|
||||
thr->shadow_stack_pos = thr->shadow_stack;
|
||||
thr->shadow_stack_end = thr->shadow_stack + kInitStackSize;
|
||||
#endif
|
||||
tctx->thr = thr;
|
||||
thr->fast_synch_epoch = tctx->epoch0;
|
||||
thr->clock.set(tid, tctx->epoch0);
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ void StackTrace::Init(const uptr *pcs, uptr cnt) {
|
|||
|
||||
void StackTrace::ObtainCurrent(ThreadState *thr, uptr toppc) {
|
||||
Reset();
|
||||
n_ = thr->shadow_stack_pos - &thr->shadow_stack[0];
|
||||
n_ = thr->shadow_stack_pos - thr->shadow_stack;
|
||||
if (n_ + !!toppc == 0)
|
||||
return;
|
||||
if (c_) {
|
||||
|
|
|
|||
|
|
@ -42,10 +42,16 @@ typedef u64 Event;
|
|||
struct TraceHeader {
|
||||
StackTrace stack0; // Start stack for the trace.
|
||||
u64 epoch0; // Start epoch for the trace.
|
||||
#ifndef TSAN_GO
|
||||
uptr stack0buf[kShadowStackSize];
|
||||
#endif
|
||||
|
||||
TraceHeader()
|
||||
#ifndef TSAN_GO
|
||||
: stack0(stack0buf, kShadowStackSize)
|
||||
#else
|
||||
: stack0()
|
||||
#endif
|
||||
, epoch0() {
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue