diff options
Diffstat (limited to 'libsanitizer/tsan/tsan_rtl.cc')
-rw-r--r-- | libsanitizer/tsan/tsan_rtl.cc | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/libsanitizer/tsan/tsan_rtl.cc b/libsanitizer/tsan/tsan_rtl.cc index 4ff26973ce3..a3e82710d90 100644 --- a/libsanitizer/tsan/tsan_rtl.cc +++ b/libsanitizer/tsan/tsan_rtl.cc @@ -137,7 +137,7 @@ static void InitializeMemoryProfile() { flags()->profile_memory, GetPid()); fd_t fd = internal_open(filename.data(), true); if (fd == kInvalidFd) { - TsanPrintf("Failed to open memory profile file '%s'\n", &filename[0]); + Printf("Failed to open memory profile file '%s'\n", &filename[0]); Die(); } internal_start_thread(&MemoryProfileThread, (void*)(uptr)fd); @@ -159,6 +159,10 @@ static void InitializeMemoryFlush() { internal_start_thread(&MemoryFlushThread, 0); } +void MapShadow(uptr addr, uptr size) { + MmapFixedNoReserve(MemToShadow(addr), size * kShadowMultiplier); +} + void Initialize(ThreadState *thr) { // Thread safe because done before all threads exist. static bool is_initialized = false; @@ -177,24 +181,32 @@ void Initialize(ThreadState *thr) { InitializeMutex(); InitializeDynamicAnnotations(); ctx = new(ctx_placeholder) Context; +#ifndef TSAN_GO InitializeShadowMemory(); +#endif ctx->dead_list_size = 0; ctx->dead_list_head = 0; ctx->dead_list_tail = 0; InitializeFlags(&ctx->flags, env); + // Setup correct file descriptor for error reports. + __sanitizer_set_report_fd(flags()->log_fileno); InitializeSuppressions(); #ifndef TSAN_GO // Initialize external symbolizer before internal threads are started. const char *external_symbolizer = flags()->external_symbolizer_path; if (external_symbolizer != 0 && external_symbolizer[0] != '\0') { - InitializeExternalSymbolizer(external_symbolizer); + if (!InitializeExternalSymbolizer(external_symbolizer)) { + Printf("Failed to start external symbolizer: '%s'\n", + external_symbolizer); + Die(); + } } #endif InitializeMemoryProfile(); InitializeMemoryFlush(); if (ctx->flags.verbosity) - TsanPrintf("***** Running under ThreadSanitizer v2 (pid %d) *****\n", + Printf("***** Running under ThreadSanitizer v2 (pid %d) *****\n", GetPid()); // Initialize thread 0. @@ -206,7 +218,7 @@ void Initialize(ThreadState *thr) { ctx->initialized = true; if (flags()->stop_on_start) { - TsanPrintf("ThreadSanitizer is suspended at startup (pid %d)." + Printf("ThreadSanitizer is suspended at startup (pid %d)." " Call __tsan_resume().\n", GetPid()); while (__tsan_resumed == 0); @@ -218,6 +230,9 @@ int Finalize(ThreadState *thr) { Context *ctx = __tsan::ctx; bool failed = false; + if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1) + SleepForMillis(flags()->atexit_sleep_ms); + // Wait for pending reports. ctx->report_mtx.Lock(); ctx->report_mtx.Unlock(); @@ -226,15 +241,20 @@ int Finalize(ThreadState *thr) { if (ctx->nreported) { failed = true; - TsanPrintf("ThreadSanitizer: reported %d warnings\n", ctx->nreported); +#ifndef TSAN_GO + Printf("ThreadSanitizer: reported %d warnings\n", ctx->nreported); +#else + Printf("Found %d data race(s)\n", ctx->nreported); +#endif } if (ctx->nmissed_expected) { failed = true; - TsanPrintf("ThreadSanitizer: missed %d expected races\n", + Printf("ThreadSanitizer: missed %d expected races\n", ctx->nmissed_expected); } + StatAggregate(ctx->stat, thr->stat); StatOutput(ctx->stat); return failed ? flags()->exitcode : 0; } @@ -298,18 +318,22 @@ static inline void HandleRace(ThreadState *thr, u64 *shadow_mem, thr->racy_state[0] = cur.raw(); thr->racy_state[1] = old.raw(); thr->racy_shadow_addr = shadow_mem; +#ifndef TSAN_GO + HACKY_CALL(__tsan_report_race); +#else ReportRace(thr); +#endif } static inline bool BothReads(Shadow s, int kAccessIsWrite) { return !kAccessIsWrite && !s.is_write(); } -static inline bool OldIsRWStronger(Shadow old, int kAccessIsWrite) { +static inline bool OldIsRWNotWeaker(Shadow old, int kAccessIsWrite) { return old.is_write() || !kAccessIsWrite; } -static inline bool OldIsRWWeaker(Shadow old, int kAccessIsWrite) { +static inline bool OldIsRWWeakerOrEqual(Shadow old, int kAccessIsWrite) { return !old.is_write() || kAccessIsWrite; } @@ -323,7 +347,7 @@ static inline bool HappensBefore(Shadow old, ThreadState *thr) { ALWAYS_INLINE void MemoryAccessImpl(ThreadState *thr, uptr addr, - int kAccessSizeLog, bool kAccessIsWrite, FastState fast_state, + int kAccessSizeLog, bool kAccessIsWrite, u64 *shadow_mem, Shadow cur) { StatInc(thr, StatMop); StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead); @@ -407,11 +431,11 @@ void MemoryAccess(ThreadState *thr, uptr pc, uptr addr, (uptr)shadow_mem[2], (uptr)shadow_mem[3]); #if TSAN_DEBUG if (!IsAppMem(addr)) { - TsanPrintf("Access to non app mem %zx\n", addr); + Printf("Access to non app mem %zx\n", addr); DCHECK(IsAppMem(addr)); } if (!IsShadowMem((uptr)shadow_mem)) { - TsanPrintf("Bad shadow addr %p (%zx)\n", shadow_mem, addr); + Printf("Bad shadow addr %p (%zx)\n", shadow_mem, addr); DCHECK(IsShadowMem((uptr)shadow_mem)); } #endif @@ -429,7 +453,7 @@ void MemoryAccess(ThreadState *thr, uptr pc, uptr addr, // That is, this call must be moved somewhere below. TraceAddEvent(thr, fast_state.epoch(), EventTypeMop, pc); - MemoryAccessImpl(thr, addr, kAccessSizeLog, kAccessIsWrite, fast_state, + MemoryAccessImpl(thr, addr, kAccessSizeLog, kAccessIsWrite, shadow_mem, cur); } @@ -491,6 +515,7 @@ void MemoryRangeImitateWrite(ThreadState *thr, uptr pc, uptr addr, uptr size) { MemoryRangeSet(thr, pc, addr, size, s.raw()); } +ALWAYS_INLINE void FuncEntry(ThreadState *thr, uptr pc) { DCHECK_EQ(thr->in_rtl, 0); StatInc(thr, StatFuncEnter); @@ -520,6 +545,7 @@ void FuncEntry(ThreadState *thr, uptr pc) { thr->shadow_stack_pos++; } +ALWAYS_INLINE void FuncExit(ThreadState *thr) { DCHECK_EQ(thr->in_rtl, 0); StatInc(thr, StatFuncExit); |