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