1 //===-- tsan_rtl.cpp ------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is a part of ThreadSanitizer (TSan), a race detector. 10 // 11 // Main file (entry points) for the TSan run-time. 12 //===----------------------------------------------------------------------===// 13 14 #include "tsan_rtl.h" 15 16 #include "sanitizer_common/sanitizer_atomic.h" 17 #include "sanitizer_common/sanitizer_common.h" 18 #include "sanitizer_common/sanitizer_file.h" 19 #include "sanitizer_common/sanitizer_libc.h" 20 #include "sanitizer_common/sanitizer_placement_new.h" 21 #include "sanitizer_common/sanitizer_stackdepot.h" 22 #include "sanitizer_common/sanitizer_symbolizer.h" 23 #include "tsan_defs.h" 24 #include "tsan_interface.h" 25 #include "tsan_mman.h" 26 #include "tsan_platform.h" 27 #include "tsan_suppressions.h" 28 #include "tsan_symbolize.h" 29 #include "ubsan/ubsan_init.h" 30 31 #ifdef __SSE3__ 32 // <emmintrin.h> transitively includes <stdlib.h>, 33 // and it's prohibited to include std headers into tsan runtime. 34 // So we do this dirty trick. 35 #define _MM_MALLOC_H_INCLUDED 36 #define __MM_MALLOC_H 37 #include <emmintrin.h> 38 typedef __m128i m128; 39 #endif 40 41 volatile int __tsan_resumed = 0; 42 43 extern "C" void __tsan_resume() { 44 __tsan_resumed = 1; 45 } 46 47 namespace __tsan { 48 49 #if !SANITIZER_GO && !SANITIZER_MAC 50 __attribute__((tls_model("initial-exec"))) 51 THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED(64); 52 #endif 53 static char ctx_placeholder[sizeof(Context)] ALIGNED(64); 54 Context *ctx; 55 56 // Can be overriden by a front-end. 57 #ifdef TSAN_EXTERNAL_HOOKS 58 bool OnFinalize(bool failed); 59 void OnInitialize(); 60 #else 61 #include <dlfcn.h> 62 SANITIZER_WEAK_CXX_DEFAULT_IMPL 63 bool OnFinalize(bool failed) { 64 #if !SANITIZER_GO 65 if (auto *ptr = dlsym(RTLD_DEFAULT, "__tsan_on_finalize")) 66 return reinterpret_cast<decltype(&__tsan_on_finalize)>(ptr)(failed); 67 #endif 68 return failed; 69 } 70 SANITIZER_WEAK_CXX_DEFAULT_IMPL 71 void OnInitialize() { 72 #if !SANITIZER_GO 73 if (auto *ptr = dlsym(RTLD_DEFAULT, "__tsan_on_initialize")) { 74 return reinterpret_cast<decltype(&__tsan_on_initialize)>(ptr)(); 75 } 76 #endif 77 } 78 #endif 79 80 static ThreadContextBase *CreateThreadContext(u32 tid) { 81 // Map thread trace when context is created. 82 char name[50]; 83 internal_snprintf(name, sizeof(name), "trace %u", tid); 84 MapThreadTrace(GetThreadTrace(tid), TraceSize() * sizeof(Event), name); 85 const uptr hdr = GetThreadTraceHeader(tid); 86 internal_snprintf(name, sizeof(name), "trace header %u", tid); 87 MapThreadTrace(hdr, sizeof(Trace), name); 88 new((void*)hdr) Trace(); 89 // We are going to use only a small part of the trace with the default 90 // value of history_size. However, the constructor writes to the whole trace. 91 // Release the unused part. 92 uptr hdr_end = hdr + sizeof(Trace); 93 hdr_end -= sizeof(TraceHeader) * (kTraceParts - TraceParts()); 94 hdr_end = RoundUp(hdr_end, GetPageSizeCached()); 95 if (hdr_end < hdr + sizeof(Trace)) { 96 ReleaseMemoryPagesToOS(hdr_end, hdr + sizeof(Trace)); 97 uptr unused = hdr + sizeof(Trace) - hdr_end; 98 if (hdr_end != (uptr)MmapFixedNoAccess(hdr_end, unused)) { 99 Report("ThreadSanitizer: failed to mprotect(%p, %p)\n", 100 hdr_end, unused); 101 CHECK("unable to mprotect" && 0); 102 } 103 } 104 void *mem = internal_alloc(sizeof(ThreadContext)); 105 return new(mem) ThreadContext(tid); 106 } 107 108 #if !SANITIZER_GO 109 static const u32 kThreadQuarantineSize = 16; 110 #else 111 static const u32 kThreadQuarantineSize = 64; 112 #endif 113 114 Context::Context() 115 : initialized(), 116 report_mtx(MutexTypeReport), 117 nreported(), 118 nmissed_expected(), 119 thread_registry(CreateThreadContext, kMaxTid, kThreadQuarantineSize, 120 kMaxTidReuse), 121 racy_mtx(MutexTypeRacy), 122 racy_stacks(), 123 racy_addresses(), 124 fired_suppressions_mtx(MutexTypeFired), 125 clock_alloc(LINKER_INITIALIZED, "clock allocator") { 126 fired_suppressions.reserve(8); 127 } 128 129 // The objects are allocated in TLS, so one may rely on zero-initialization. 130 ThreadState::ThreadState(Context *ctx, u32 tid, int unique_id, u64 epoch, 131 unsigned reuse_count, uptr stk_addr, uptr stk_size, 132 uptr tls_addr, uptr tls_size) 133 : fast_state(tid, epoch) 134 // Do not touch these, rely on zero initialization, 135 // they may be accessed before the ctor. 136 // , ignore_reads_and_writes() 137 // , ignore_interceptors() 138 , 139 clock(tid, reuse_count) 140 #if !SANITIZER_GO 141 , 142 jmp_bufs() 143 #endif 144 , 145 tid(tid), 146 unique_id(unique_id), 147 stk_addr(stk_addr), 148 stk_size(stk_size), 149 tls_addr(tls_addr), 150 tls_size(tls_size) 151 #if !SANITIZER_GO 152 , 153 last_sleep_clock(tid) 154 #endif 155 { 156 } 157 158 #if !SANITIZER_GO 159 static void MemoryProfiler(Context *ctx, fd_t fd, int i) { 160 uptr n_threads; 161 uptr n_running_threads; 162 ctx->thread_registry.GetNumberOfThreads(&n_threads, &n_running_threads); 163 InternalMmapVector<char> buf(4096); 164 WriteMemoryProfile(buf.data(), buf.size(), n_threads, n_running_threads); 165 WriteToFile(fd, buf.data(), internal_strlen(buf.data())); 166 } 167 168 static void *BackgroundThread(void *arg) { 169 // This is a non-initialized non-user thread, nothing to see here. 170 // We don't use ScopedIgnoreInterceptors, because we want ignores to be 171 // enabled even when the thread function exits (e.g. during pthread thread 172 // shutdown code). 173 cur_thread_init(); 174 cur_thread()->ignore_interceptors++; 175 const u64 kMs2Ns = 1000 * 1000; 176 177 fd_t mprof_fd = kInvalidFd; 178 if (flags()->profile_memory && flags()->profile_memory[0]) { 179 if (internal_strcmp(flags()->profile_memory, "stdout") == 0) { 180 mprof_fd = 1; 181 } else if (internal_strcmp(flags()->profile_memory, "stderr") == 0) { 182 mprof_fd = 2; 183 } else { 184 InternalScopedString filename; 185 filename.append("%s.%d", flags()->profile_memory, (int)internal_getpid()); 186 fd_t fd = OpenFile(filename.data(), WrOnly); 187 if (fd == kInvalidFd) { 188 Printf("ThreadSanitizer: failed to open memory profile file '%s'\n", 189 filename.data()); 190 } else { 191 mprof_fd = fd; 192 } 193 } 194 } 195 196 u64 last_flush = NanoTime(); 197 uptr last_rss = 0; 198 for (int i = 0; 199 atomic_load(&ctx->stop_background_thread, memory_order_relaxed) == 0; 200 i++) { 201 SleepForMillis(100); 202 u64 now = NanoTime(); 203 204 // Flush memory if requested. 205 if (flags()->flush_memory_ms > 0) { 206 if (last_flush + flags()->flush_memory_ms * kMs2Ns < now) { 207 VPrintf(1, "ThreadSanitizer: periodic memory flush\n"); 208 FlushShadowMemory(); 209 last_flush = NanoTime(); 210 } 211 } 212 // GetRSS can be expensive on huge programs, so don't do it every 100ms. 213 if (flags()->memory_limit_mb > 0) { 214 uptr rss = GetRSS(); 215 uptr limit = uptr(flags()->memory_limit_mb) << 20; 216 VPrintf(1, "ThreadSanitizer: memory flush check" 217 " RSS=%llu LAST=%llu LIMIT=%llu\n", 218 (u64)rss >> 20, (u64)last_rss >> 20, (u64)limit >> 20); 219 if (2 * rss > limit + last_rss) { 220 VPrintf(1, "ThreadSanitizer: flushing memory due to RSS\n"); 221 FlushShadowMemory(); 222 rss = GetRSS(); 223 VPrintf(1, "ThreadSanitizer: memory flushed RSS=%llu\n", (u64)rss>>20); 224 } 225 last_rss = rss; 226 } 227 228 // Write memory profile if requested. 229 if (mprof_fd != kInvalidFd) 230 MemoryProfiler(ctx, mprof_fd, i); 231 232 // Flush symbolizer cache if requested. 233 if (flags()->flush_symbolizer_ms > 0) { 234 u64 last = atomic_load(&ctx->last_symbolize_time_ns, 235 memory_order_relaxed); 236 if (last != 0 && last + flags()->flush_symbolizer_ms * kMs2Ns < now) { 237 Lock l(&ctx->report_mtx); 238 ScopedErrorReportLock l2; 239 SymbolizeFlush(); 240 atomic_store(&ctx->last_symbolize_time_ns, 0, memory_order_relaxed); 241 } 242 } 243 } 244 return nullptr; 245 } 246 247 static void StartBackgroundThread() { 248 ctx->background_thread = internal_start_thread(&BackgroundThread, 0); 249 } 250 251 #ifndef __mips__ 252 static void StopBackgroundThread() { 253 atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed); 254 internal_join_thread(ctx->background_thread); 255 ctx->background_thread = 0; 256 } 257 #endif 258 #endif 259 260 void DontNeedShadowFor(uptr addr, uptr size) { 261 ReleaseMemoryPagesToOS(MemToShadow(addr), MemToShadow(addr + size)); 262 } 263 264 #if !SANITIZER_GO 265 void UnmapShadow(ThreadState *thr, uptr addr, uptr size) { 266 if (size == 0) return; 267 DontNeedShadowFor(addr, size); 268 ScopedGlobalProcessor sgp; 269 ctx->metamap.ResetRange(thr->proc(), addr, size); 270 } 271 #endif 272 273 void MapShadow(uptr addr, uptr size) { 274 // Global data is not 64K aligned, but there are no adjacent mappings, 275 // so we can get away with unaligned mapping. 276 // CHECK_EQ(addr, addr & ~((64 << 10) - 1)); // windows wants 64K alignment 277 const uptr kPageSize = GetPageSizeCached(); 278 uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), kPageSize); 279 uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), kPageSize); 280 if (!MmapFixedSuperNoReserve(shadow_begin, shadow_end - shadow_begin, 281 "shadow")) 282 Die(); 283 284 // Meta shadow is 2:1, so tread carefully. 285 static bool data_mapped = false; 286 static uptr mapped_meta_end = 0; 287 uptr meta_begin = (uptr)MemToMeta(addr); 288 uptr meta_end = (uptr)MemToMeta(addr + size); 289 meta_begin = RoundDownTo(meta_begin, 64 << 10); 290 meta_end = RoundUpTo(meta_end, 64 << 10); 291 if (!data_mapped) { 292 // First call maps data+bss. 293 data_mapped = true; 294 if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin, 295 "meta shadow")) 296 Die(); 297 } else { 298 // Mapping continous heap. 299 // Windows wants 64K alignment. 300 meta_begin = RoundDownTo(meta_begin, 64 << 10); 301 meta_end = RoundUpTo(meta_end, 64 << 10); 302 if (meta_end <= mapped_meta_end) 303 return; 304 if (meta_begin < mapped_meta_end) 305 meta_begin = mapped_meta_end; 306 if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin, 307 "meta shadow")) 308 Die(); 309 mapped_meta_end = meta_end; 310 } 311 VPrintf(2, "mapped meta shadow for (%p-%p) at (%p-%p)\n", 312 addr, addr+size, meta_begin, meta_end); 313 } 314 315 void MapThreadTrace(uptr addr, uptr size, const char *name) { 316 DPrintf("#0: Mapping trace at %p-%p(0x%zx)\n", addr, addr + size, size); 317 CHECK_GE(addr, TraceMemBeg()); 318 CHECK_LE(addr + size, TraceMemEnd()); 319 CHECK_EQ(addr, addr & ~((64 << 10) - 1)); // windows wants 64K alignment 320 if (!MmapFixedSuperNoReserve(addr, size, name)) { 321 Printf("FATAL: ThreadSanitizer can not mmap thread trace (%p/%p)\n", 322 addr, size); 323 Die(); 324 } 325 } 326 327 static void CheckShadowMapping() { 328 uptr beg, end; 329 for (int i = 0; GetUserRegion(i, &beg, &end); i++) { 330 // Skip cases for empty regions (heap definition for architectures that 331 // do not use 64-bit allocator). 332 if (beg == end) 333 continue; 334 VPrintf(3, "checking shadow region %p-%p\n", beg, end); 335 uptr prev = 0; 336 for (uptr p0 = beg; p0 <= end; p0 += (end - beg) / 4) { 337 for (int x = -(int)kShadowCell; x <= (int)kShadowCell; x += kShadowCell) { 338 const uptr p = RoundDown(p0 + x, kShadowCell); 339 if (p < beg || p >= end) 340 continue; 341 const uptr s = MemToShadow(p); 342 const uptr m = (uptr)MemToMeta(p); 343 VPrintf(3, " checking pointer %p: shadow=%p meta=%p\n", p, s, m); 344 CHECK(IsAppMem(p)); 345 CHECK(IsShadowMem(s)); 346 CHECK_EQ(p, ShadowToMem(s)); 347 CHECK(IsMetaMem(m)); 348 if (prev) { 349 // Ensure that shadow and meta mappings are linear within a single 350 // user range. Lots of code that processes memory ranges assumes it. 351 const uptr prev_s = MemToShadow(prev); 352 const uptr prev_m = (uptr)MemToMeta(prev); 353 CHECK_EQ(s - prev_s, (p - prev) * kShadowMultiplier); 354 CHECK_EQ((m - prev_m) / kMetaShadowSize, 355 (p - prev) / kMetaShadowCell); 356 } 357 prev = p; 358 } 359 } 360 } 361 } 362 363 #if !SANITIZER_GO 364 static void OnStackUnwind(const SignalContext &sig, const void *, 365 BufferedStackTrace *stack) { 366 stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, 367 common_flags()->fast_unwind_on_fatal); 368 } 369 370 static void TsanOnDeadlySignal(int signo, void *siginfo, void *context) { 371 HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr); 372 } 373 #endif 374 375 void CheckUnwind() { 376 // There is high probability that interceptors will check-fail as well, 377 // on the other hand there is no sense in processing interceptors 378 // since we are going to die soon. 379 ScopedIgnoreInterceptors ignore; 380 #if !SANITIZER_GO 381 cur_thread()->ignore_sync++; 382 cur_thread()->ignore_reads_and_writes++; 383 #endif 384 PrintCurrentStackSlow(StackTrace::GetCurrentPc()); 385 } 386 387 bool is_initialized; 388 389 void Initialize(ThreadState *thr) { 390 // Thread safe because done before all threads exist. 391 if (is_initialized) 392 return; 393 is_initialized = true; 394 // We are not ready to handle interceptors yet. 395 ScopedIgnoreInterceptors ignore; 396 SanitizerToolName = "ThreadSanitizer"; 397 // Install tool-specific callbacks in sanitizer_common. 398 SetCheckUnwindCallback(CheckUnwind); 399 400 ctx = new(ctx_placeholder) Context; 401 const char *env_name = SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS"; 402 const char *options = GetEnv(env_name); 403 CacheBinaryName(); 404 CheckASLR(); 405 InitializeFlags(&ctx->flags, options, env_name); 406 AvoidCVE_2016_2143(); 407 __sanitizer::InitializePlatformEarly(); 408 __tsan::InitializePlatformEarly(); 409 410 #if !SANITIZER_GO 411 // Re-exec ourselves if we need to set additional env or command line args. 412 MaybeReexec(); 413 414 InitializeAllocator(); 415 ReplaceSystemMalloc(); 416 #endif 417 if (common_flags()->detect_deadlocks) 418 ctx->dd = DDetector::Create(flags()); 419 Processor *proc = ProcCreate(); 420 ProcWire(proc, thr); 421 InitializeInterceptors(); 422 CheckShadowMapping(); 423 InitializePlatform(); 424 InitializeDynamicAnnotations(); 425 #if !SANITIZER_GO 426 InitializeShadowMemory(); 427 InitializeAllocatorLate(); 428 InstallDeadlySignalHandlers(TsanOnDeadlySignal); 429 #endif 430 // Setup correct file descriptor for error reports. 431 __sanitizer_set_report_path(common_flags()->log_path); 432 InitializeSuppressions(); 433 #if !SANITIZER_GO 434 InitializeLibIgnore(); 435 Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer); 436 #endif 437 438 VPrintf(1, "***** Running under ThreadSanitizer v2 (pid %d) *****\n", 439 (int)internal_getpid()); 440 441 // Initialize thread 0. 442 int tid = ThreadCreate(thr, 0, 0, true); 443 CHECK_EQ(tid, 0); 444 ThreadStart(thr, tid, GetTid(), ThreadType::Regular); 445 #if TSAN_CONTAINS_UBSAN 446 __ubsan::InitAsPlugin(); 447 #endif 448 ctx->initialized = true; 449 450 #if !SANITIZER_GO 451 Symbolizer::LateInitialize(); 452 #endif 453 454 if (flags()->stop_on_start) { 455 Printf("ThreadSanitizer is suspended at startup (pid %d)." 456 " Call __tsan_resume().\n", 457 (int)internal_getpid()); 458 while (__tsan_resumed == 0) {} 459 } 460 461 OnInitialize(); 462 } 463 464 void MaybeSpawnBackgroundThread() { 465 // On MIPS, TSan initialization is run before 466 // __pthread_initialize_minimal_internal() is finished, so we can not spawn 467 // new threads. 468 #if !SANITIZER_GO && !defined(__mips__) 469 static atomic_uint32_t bg_thread = {}; 470 if (atomic_load(&bg_thread, memory_order_relaxed) == 0 && 471 atomic_exchange(&bg_thread, 1, memory_order_relaxed) == 0) { 472 StartBackgroundThread(); 473 SetSandboxingCallback(StopBackgroundThread); 474 } 475 #endif 476 } 477 478 479 int Finalize(ThreadState *thr) { 480 bool failed = false; 481 482 if (common_flags()->print_module_map == 1) 483 DumpProcessMap(); 484 485 if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1) 486 SleepForMillis(flags()->atexit_sleep_ms); 487 488 // Wait for pending reports. 489 ctx->report_mtx.Lock(); 490 { ScopedErrorReportLock l; } 491 ctx->report_mtx.Unlock(); 492 493 #if !SANITIZER_GO 494 if (Verbosity()) AllocatorPrintStats(); 495 #endif 496 497 ThreadFinalize(thr); 498 499 if (ctx->nreported) { 500 failed = true; 501 #if !SANITIZER_GO 502 Printf("ThreadSanitizer: reported %d warnings\n", ctx->nreported); 503 #else 504 Printf("Found %d data race(s)\n", ctx->nreported); 505 #endif 506 } 507 508 if (ctx->nmissed_expected) { 509 failed = true; 510 Printf("ThreadSanitizer: missed %d expected races\n", 511 ctx->nmissed_expected); 512 } 513 514 if (common_flags()->print_suppressions) 515 PrintMatchedSuppressions(); 516 #if !SANITIZER_GO 517 if (flags()->print_benign) 518 PrintMatchedBenignRaces(); 519 #endif 520 521 failed = OnFinalize(failed); 522 523 return failed ? common_flags()->exitcode : 0; 524 } 525 526 #if !SANITIZER_GO 527 void ForkBefore(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { 528 ctx->thread_registry.Lock(); 529 ctx->report_mtx.Lock(); 530 ScopedErrorReportLock::Lock(); 531 // Suppress all reports in the pthread_atfork callbacks. 532 // Reports will deadlock on the report_mtx. 533 // We could ignore sync operations as well, 534 // but so far it's unclear if it will do more good or harm. 535 // Unnecessarily ignoring things can lead to false positives later. 536 thr->suppress_reports++; 537 // On OS X, REAL(fork) can call intercepted functions (OSSpinLockLock), and 538 // we'll assert in CheckNoLocks() unless we ignore interceptors. 539 thr->ignore_interceptors++; 540 } 541 542 void ForkParentAfter(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { 543 thr->suppress_reports--; // Enabled in ForkBefore. 544 thr->ignore_interceptors--; 545 ScopedErrorReportLock::Unlock(); 546 ctx->report_mtx.Unlock(); 547 ctx->thread_registry.Unlock(); 548 } 549 550 void ForkChildAfter(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { 551 thr->suppress_reports--; // Enabled in ForkBefore. 552 thr->ignore_interceptors--; 553 ScopedErrorReportLock::Unlock(); 554 ctx->report_mtx.Unlock(); 555 ctx->thread_registry.Unlock(); 556 557 uptr nthread = 0; 558 ctx->thread_registry.GetNumberOfThreads(0, 0, &nthread /* alive threads */); 559 VPrintf(1, "ThreadSanitizer: forked new process with pid %d," 560 " parent had %d threads\n", (int)internal_getpid(), (int)nthread); 561 if (nthread == 1) { 562 StartBackgroundThread(); 563 } else { 564 // We've just forked a multi-threaded process. We cannot reasonably function 565 // after that (some mutexes may be locked before fork). So just enable 566 // ignores for everything in the hope that we will exec soon. 567 ctx->after_multithreaded_fork = true; 568 thr->ignore_interceptors++; 569 ThreadIgnoreBegin(thr, pc); 570 ThreadIgnoreSyncBegin(thr, pc); 571 } 572 } 573 #endif 574 575 #if SANITIZER_GO 576 NOINLINE 577 void GrowShadowStack(ThreadState *thr) { 578 const int sz = thr->shadow_stack_end - thr->shadow_stack; 579 const int newsz = 2 * sz; 580 uptr *newstack = (uptr *)internal_alloc(newsz * sizeof(uptr)); 581 internal_memcpy(newstack, thr->shadow_stack, sz * sizeof(uptr)); 582 internal_free(thr->shadow_stack); 583 thr->shadow_stack = newstack; 584 thr->shadow_stack_pos = newstack + sz; 585 thr->shadow_stack_end = newstack + newsz; 586 } 587 #endif 588 589 u32 CurrentStackId(ThreadState *thr, uptr pc) { 590 if (!thr->is_inited) // May happen during bootstrap. 591 return 0; 592 if (pc != 0) { 593 #if !SANITIZER_GO 594 DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end); 595 #else 596 if (thr->shadow_stack_pos == thr->shadow_stack_end) 597 GrowShadowStack(thr); 598 #endif 599 thr->shadow_stack_pos[0] = pc; 600 thr->shadow_stack_pos++; 601 } 602 u32 id = StackDepotPut( 603 StackTrace(thr->shadow_stack, thr->shadow_stack_pos - thr->shadow_stack)); 604 if (pc != 0) 605 thr->shadow_stack_pos--; 606 return id; 607 } 608 609 void TraceSwitch(ThreadState *thr) { 610 #if !SANITIZER_GO 611 if (ctx->after_multithreaded_fork) 612 return; 613 #endif 614 thr->nomalloc++; 615 Trace *thr_trace = ThreadTrace(thr->tid); 616 Lock l(&thr_trace->mtx); 617 unsigned trace = (thr->fast_state.epoch() / kTracePartSize) % TraceParts(); 618 TraceHeader *hdr = &thr_trace->headers[trace]; 619 hdr->epoch0 = thr->fast_state.epoch(); 620 ObtainCurrentStack(thr, 0, &hdr->stack0); 621 hdr->mset0 = thr->mset; 622 thr->nomalloc--; 623 } 624 625 Trace *ThreadTrace(int tid) { 626 return (Trace*)GetThreadTraceHeader(tid); 627 } 628 629 uptr TraceTopPC(ThreadState *thr) { 630 Event *events = (Event*)GetThreadTrace(thr->tid); 631 uptr pc = events[thr->fast_state.GetTracePos()]; 632 return pc; 633 } 634 635 uptr TraceSize() { 636 return (uptr)(1ull << (kTracePartSizeBits + flags()->history_size + 1)); 637 } 638 639 uptr TraceParts() { 640 return TraceSize() / kTracePartSize; 641 } 642 643 #if !SANITIZER_GO 644 extern "C" void __tsan_trace_switch() { 645 TraceSwitch(cur_thread()); 646 } 647 648 extern "C" void __tsan_report_race() { 649 ReportRace(cur_thread()); 650 } 651 #endif 652 653 ALWAYS_INLINE 654 Shadow LoadShadow(u64 *p) { 655 u64 raw = atomic_load((atomic_uint64_t*)p, memory_order_relaxed); 656 return Shadow(raw); 657 } 658 659 ALWAYS_INLINE 660 void StoreShadow(u64 *sp, u64 s) { 661 atomic_store((atomic_uint64_t*)sp, s, memory_order_relaxed); 662 } 663 664 ALWAYS_INLINE 665 void StoreIfNotYetStored(u64 *sp, u64 *s) { 666 StoreShadow(sp, *s); 667 *s = 0; 668 } 669 670 ALWAYS_INLINE 671 void HandleRace(ThreadState *thr, u64 *shadow_mem, 672 Shadow cur, Shadow old) { 673 thr->racy_state[0] = cur.raw(); 674 thr->racy_state[1] = old.raw(); 675 thr->racy_shadow_addr = shadow_mem; 676 #if !SANITIZER_GO 677 HACKY_CALL(__tsan_report_race); 678 #else 679 ReportRace(thr); 680 #endif 681 } 682 683 static inline bool HappensBefore(Shadow old, ThreadState *thr) { 684 return thr->clock.get(old.TidWithIgnore()) >= old.epoch(); 685 } 686 687 ALWAYS_INLINE 688 void MemoryAccessImpl1(ThreadState *thr, uptr addr, 689 int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic, 690 u64 *shadow_mem, Shadow cur) { 691 692 // This potentially can live in an MMX/SSE scratch register. 693 // The required intrinsics are: 694 // __m128i _mm_move_epi64(__m128i*); 695 // _mm_storel_epi64(u64*, __m128i); 696 u64 store_word = cur.raw(); 697 bool stored = false; 698 699 // scan all the shadow values and dispatch to 4 categories: 700 // same, replace, candidate and race (see comments below). 701 // we consider only 3 cases regarding access sizes: 702 // equal, intersect and not intersect. initially I considered 703 // larger and smaller as well, it allowed to replace some 704 // 'candidates' with 'same' or 'replace', but I think 705 // it's just not worth it (performance- and complexity-wise). 706 707 Shadow old(0); 708 709 // It release mode we manually unroll the loop, 710 // because empirically gcc generates better code this way. 711 // However, we can't afford unrolling in debug mode, because the function 712 // consumes almost 4K of stack. Gtest gives only 4K of stack to death test 713 // threads, which is not enough for the unrolled loop. 714 #if SANITIZER_DEBUG 715 for (int idx = 0; idx < 4; idx++) { 716 #include "tsan_update_shadow_word_inl.h" 717 } 718 #else 719 int idx = 0; 720 #include "tsan_update_shadow_word_inl.h" 721 idx = 1; 722 if (stored) { 723 #include "tsan_update_shadow_word_inl.h" 724 } else { 725 #include "tsan_update_shadow_word_inl.h" 726 } 727 idx = 2; 728 if (stored) { 729 #include "tsan_update_shadow_word_inl.h" 730 } else { 731 #include "tsan_update_shadow_word_inl.h" 732 } 733 idx = 3; 734 if (stored) { 735 #include "tsan_update_shadow_word_inl.h" 736 } else { 737 #include "tsan_update_shadow_word_inl.h" 738 } 739 #endif 740 741 // we did not find any races and had already stored 742 // the current access info, so we are done 743 if (LIKELY(stored)) 744 return; 745 // choose a random candidate slot and replace it 746 StoreShadow(shadow_mem + (cur.epoch() % kShadowCnt), store_word); 747 return; 748 RACE: 749 HandleRace(thr, shadow_mem, cur, old); 750 return; 751 } 752 753 void UnalignedMemoryAccess(ThreadState *thr, uptr pc, uptr addr, 754 int size, bool kAccessIsWrite, bool kIsAtomic) { 755 while (size) { 756 int size1 = 1; 757 int kAccessSizeLog = kSizeLog1; 758 if (size >= 8 && (addr & ~7) == ((addr + 7) & ~7)) { 759 size1 = 8; 760 kAccessSizeLog = kSizeLog8; 761 } else if (size >= 4 && (addr & ~7) == ((addr + 3) & ~7)) { 762 size1 = 4; 763 kAccessSizeLog = kSizeLog4; 764 } else if (size >= 2 && (addr & ~7) == ((addr + 1) & ~7)) { 765 size1 = 2; 766 kAccessSizeLog = kSizeLog2; 767 } 768 MemoryAccess(thr, pc, addr, kAccessSizeLog, kAccessIsWrite, kIsAtomic); 769 addr += size1; 770 size -= size1; 771 } 772 } 773 774 ALWAYS_INLINE 775 bool ContainsSameAccessSlow(u64 *s, u64 a, u64 sync_epoch, bool is_write) { 776 Shadow cur(a); 777 for (uptr i = 0; i < kShadowCnt; i++) { 778 Shadow old(LoadShadow(&s[i])); 779 if (Shadow::Addr0AndSizeAreEqual(cur, old) && 780 old.TidWithIgnore() == cur.TidWithIgnore() && 781 old.epoch() > sync_epoch && 782 old.IsAtomic() == cur.IsAtomic() && 783 old.IsRead() <= cur.IsRead()) 784 return true; 785 } 786 return false; 787 } 788 789 #if defined(__SSE3__) 790 #define SHUF(v0, v1, i0, i1, i2, i3) _mm_castps_si128(_mm_shuffle_ps( \ 791 _mm_castsi128_ps(v0), _mm_castsi128_ps(v1), \ 792 (i0)*1 + (i1)*4 + (i2)*16 + (i3)*64)) 793 ALWAYS_INLINE 794 bool ContainsSameAccessFast(u64 *s, u64 a, u64 sync_epoch, bool is_write) { 795 // This is an optimized version of ContainsSameAccessSlow. 796 // load current access into access[0:63] 797 const m128 access = _mm_cvtsi64_si128(a); 798 // duplicate high part of access in addr0: 799 // addr0[0:31] = access[32:63] 800 // addr0[32:63] = access[32:63] 801 // addr0[64:95] = access[32:63] 802 // addr0[96:127] = access[32:63] 803 const m128 addr0 = SHUF(access, access, 1, 1, 1, 1); 804 // load 4 shadow slots 805 const m128 shadow0 = _mm_load_si128((__m128i*)s); 806 const m128 shadow1 = _mm_load_si128((__m128i*)s + 1); 807 // load high parts of 4 shadow slots into addr_vect: 808 // addr_vect[0:31] = shadow0[32:63] 809 // addr_vect[32:63] = shadow0[96:127] 810 // addr_vect[64:95] = shadow1[32:63] 811 // addr_vect[96:127] = shadow1[96:127] 812 m128 addr_vect = SHUF(shadow0, shadow1, 1, 3, 1, 3); 813 if (!is_write) { 814 // set IsRead bit in addr_vect 815 const m128 rw_mask1 = _mm_cvtsi64_si128(1<<15); 816 const m128 rw_mask = SHUF(rw_mask1, rw_mask1, 0, 0, 0, 0); 817 addr_vect = _mm_or_si128(addr_vect, rw_mask); 818 } 819 // addr0 == addr_vect? 820 const m128 addr_res = _mm_cmpeq_epi32(addr0, addr_vect); 821 // epoch1[0:63] = sync_epoch 822 const m128 epoch1 = _mm_cvtsi64_si128(sync_epoch); 823 // epoch[0:31] = sync_epoch[0:31] 824 // epoch[32:63] = sync_epoch[0:31] 825 // epoch[64:95] = sync_epoch[0:31] 826 // epoch[96:127] = sync_epoch[0:31] 827 const m128 epoch = SHUF(epoch1, epoch1, 0, 0, 0, 0); 828 // load low parts of shadow cell epochs into epoch_vect: 829 // epoch_vect[0:31] = shadow0[0:31] 830 // epoch_vect[32:63] = shadow0[64:95] 831 // epoch_vect[64:95] = shadow1[0:31] 832 // epoch_vect[96:127] = shadow1[64:95] 833 const m128 epoch_vect = SHUF(shadow0, shadow1, 0, 2, 0, 2); 834 // epoch_vect >= sync_epoch? 835 const m128 epoch_res = _mm_cmpgt_epi32(epoch_vect, epoch); 836 // addr_res & epoch_res 837 const m128 res = _mm_and_si128(addr_res, epoch_res); 838 // mask[0] = res[7] 839 // mask[1] = res[15] 840 // ... 841 // mask[15] = res[127] 842 const int mask = _mm_movemask_epi8(res); 843 return mask != 0; 844 } 845 #endif 846 847 ALWAYS_INLINE 848 bool ContainsSameAccess(u64 *s, u64 a, u64 sync_epoch, bool is_write) { 849 #if defined(__SSE3__) 850 bool res = ContainsSameAccessFast(s, a, sync_epoch, is_write); 851 // NOTE: this check can fail if the shadow is concurrently mutated 852 // by other threads. But it still can be useful if you modify 853 // ContainsSameAccessFast and want to ensure that it's not completely broken. 854 // DCHECK_EQ(res, ContainsSameAccessSlow(s, a, sync_epoch, is_write)); 855 return res; 856 #else 857 return ContainsSameAccessSlow(s, a, sync_epoch, is_write); 858 #endif 859 } 860 861 ALWAYS_INLINE USED 862 void MemoryAccess(ThreadState *thr, uptr pc, uptr addr, 863 int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic) { 864 u64 *shadow_mem = (u64*)MemToShadow(addr); 865 DPrintf2("#%d: MemoryAccess: @%p %p size=%d" 866 " is_write=%d shadow_mem=%p {%zx, %zx, %zx, %zx}\n", 867 (int)thr->fast_state.tid(), (void*)pc, (void*)addr, 868 (int)(1 << kAccessSizeLog), kAccessIsWrite, shadow_mem, 869 (uptr)shadow_mem[0], (uptr)shadow_mem[1], 870 (uptr)shadow_mem[2], (uptr)shadow_mem[3]); 871 #if SANITIZER_DEBUG 872 if (!IsAppMem(addr)) { 873 Printf("Access to non app mem %zx\n", addr); 874 DCHECK(IsAppMem(addr)); 875 } 876 if (!IsShadowMem((uptr)shadow_mem)) { 877 Printf("Bad shadow addr %p (%zx)\n", shadow_mem, addr); 878 DCHECK(IsShadowMem((uptr)shadow_mem)); 879 } 880 #endif 881 882 if (!SANITIZER_GO && !kAccessIsWrite && *shadow_mem == kShadowRodata) { 883 // Access to .rodata section, no races here. 884 // Measurements show that it can be 10-20% of all memory accesses. 885 return; 886 } 887 888 FastState fast_state = thr->fast_state; 889 if (UNLIKELY(fast_state.GetIgnoreBit())) { 890 return; 891 } 892 893 Shadow cur(fast_state); 894 cur.SetAddr0AndSizeLog(addr & 7, kAccessSizeLog); 895 cur.SetWrite(kAccessIsWrite); 896 cur.SetAtomic(kIsAtomic); 897 898 if (LIKELY(ContainsSameAccess(shadow_mem, cur.raw(), 899 thr->fast_synch_epoch, kAccessIsWrite))) { 900 return; 901 } 902 903 if (kCollectHistory) { 904 fast_state.IncrementEpoch(); 905 thr->fast_state = fast_state; 906 TraceAddEvent(thr, fast_state, EventTypeMop, pc); 907 cur.IncrementEpoch(); 908 } 909 910 MemoryAccessImpl1(thr, addr, kAccessSizeLog, kAccessIsWrite, kIsAtomic, 911 shadow_mem, cur); 912 } 913 914 // Called by MemoryAccessRange in tsan_rtl_thread.cpp 915 ALWAYS_INLINE USED 916 void MemoryAccessImpl(ThreadState *thr, uptr addr, 917 int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic, 918 u64 *shadow_mem, Shadow cur) { 919 if (LIKELY(ContainsSameAccess(shadow_mem, cur.raw(), 920 thr->fast_synch_epoch, kAccessIsWrite))) { 921 return; 922 } 923 924 MemoryAccessImpl1(thr, addr, kAccessSizeLog, kAccessIsWrite, kIsAtomic, 925 shadow_mem, cur); 926 } 927 928 static void MemoryRangeSet(ThreadState *thr, uptr pc, uptr addr, uptr size, 929 u64 val) { 930 (void)thr; 931 (void)pc; 932 if (size == 0) 933 return; 934 // FIXME: fix me. 935 uptr offset = addr % kShadowCell; 936 if (offset) { 937 offset = kShadowCell - offset; 938 if (size <= offset) 939 return; 940 addr += offset; 941 size -= offset; 942 } 943 DCHECK_EQ(addr % 8, 0); 944 // If a user passes some insane arguments (memset(0)), 945 // let it just crash as usual. 946 if (!IsAppMem(addr) || !IsAppMem(addr + size - 1)) 947 return; 948 // Don't want to touch lots of shadow memory. 949 // If a program maps 10MB stack, there is no need reset the whole range. 950 size = (size + (kShadowCell - 1)) & ~(kShadowCell - 1); 951 // UnmapOrDie/MmapFixedNoReserve does not work on Windows. 952 if (SANITIZER_WINDOWS || size < common_flags()->clear_shadow_mmap_threshold) { 953 u64 *p = (u64*)MemToShadow(addr); 954 CHECK(IsShadowMem((uptr)p)); 955 CHECK(IsShadowMem((uptr)(p + size * kShadowCnt / kShadowCell - 1))); 956 // FIXME: may overwrite a part outside the region 957 for (uptr i = 0; i < size / kShadowCell * kShadowCnt;) { 958 p[i++] = val; 959 for (uptr j = 1; j < kShadowCnt; j++) 960 p[i++] = 0; 961 } 962 } else { 963 // The region is big, reset only beginning and end. 964 const uptr kPageSize = GetPageSizeCached(); 965 u64 *begin = (u64*)MemToShadow(addr); 966 u64 *end = begin + size / kShadowCell * kShadowCnt; 967 u64 *p = begin; 968 // Set at least first kPageSize/2 to page boundary. 969 while ((p < begin + kPageSize / kShadowSize / 2) || ((uptr)p % kPageSize)) { 970 *p++ = val; 971 for (uptr j = 1; j < kShadowCnt; j++) 972 *p++ = 0; 973 } 974 // Reset middle part. 975 u64 *p1 = p; 976 p = RoundDown(end, kPageSize); 977 if (!MmapFixedSuperNoReserve((uptr)p1, (uptr)p - (uptr)p1)) 978 Die(); 979 // Set the ending. 980 while (p < end) { 981 *p++ = val; 982 for (uptr j = 1; j < kShadowCnt; j++) 983 *p++ = 0; 984 } 985 } 986 } 987 988 void MemoryResetRange(ThreadState *thr, uptr pc, uptr addr, uptr size) { 989 MemoryRangeSet(thr, pc, addr, size, 0); 990 } 991 992 void MemoryRangeFreed(ThreadState *thr, uptr pc, uptr addr, uptr size) { 993 // Processing more than 1k (4k of shadow) is expensive, 994 // can cause excessive memory consumption (user does not necessary touch 995 // the whole range) and most likely unnecessary. 996 if (size > 1024) 997 size = 1024; 998 CHECK_EQ(thr->is_freeing, false); 999 thr->is_freeing = true; 1000 MemoryAccessRange(thr, pc, addr, size, true); 1001 thr->is_freeing = false; 1002 if (kCollectHistory) { 1003 thr->fast_state.IncrementEpoch(); 1004 TraceAddEvent(thr, thr->fast_state, EventTypeMop, pc); 1005 } 1006 Shadow s(thr->fast_state); 1007 s.ClearIgnoreBit(); 1008 s.MarkAsFreed(); 1009 s.SetWrite(true); 1010 s.SetAddr0AndSizeLog(0, 3); 1011 MemoryRangeSet(thr, pc, addr, size, s.raw()); 1012 } 1013 1014 void MemoryRangeImitateWrite(ThreadState *thr, uptr pc, uptr addr, uptr size) { 1015 if (kCollectHistory) { 1016 thr->fast_state.IncrementEpoch(); 1017 TraceAddEvent(thr, thr->fast_state, EventTypeMop, pc); 1018 } 1019 Shadow s(thr->fast_state); 1020 s.ClearIgnoreBit(); 1021 s.SetWrite(true); 1022 s.SetAddr0AndSizeLog(0, 3); 1023 MemoryRangeSet(thr, pc, addr, size, s.raw()); 1024 } 1025 1026 void MemoryRangeImitateWriteOrResetRange(ThreadState *thr, uptr pc, uptr addr, 1027 uptr size) { 1028 if (thr->ignore_reads_and_writes == 0) 1029 MemoryRangeImitateWrite(thr, pc, addr, size); 1030 else 1031 MemoryResetRange(thr, pc, addr, size); 1032 } 1033 1034 ALWAYS_INLINE USED 1035 void FuncEntry(ThreadState *thr, uptr pc) { 1036 DPrintf2("#%d: FuncEntry %p\n", (int)thr->fast_state.tid(), (void*)pc); 1037 if (kCollectHistory) { 1038 thr->fast_state.IncrementEpoch(); 1039 TraceAddEvent(thr, thr->fast_state, EventTypeFuncEnter, pc); 1040 } 1041 1042 // Shadow stack maintenance can be replaced with 1043 // stack unwinding during trace switch (which presumably must be faster). 1044 DCHECK_GE(thr->shadow_stack_pos, thr->shadow_stack); 1045 #if !SANITIZER_GO 1046 DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end); 1047 #else 1048 if (thr->shadow_stack_pos == thr->shadow_stack_end) 1049 GrowShadowStack(thr); 1050 #endif 1051 thr->shadow_stack_pos[0] = pc; 1052 thr->shadow_stack_pos++; 1053 } 1054 1055 ALWAYS_INLINE USED 1056 void FuncExit(ThreadState *thr) { 1057 DPrintf2("#%d: FuncExit\n", (int)thr->fast_state.tid()); 1058 if (kCollectHistory) { 1059 thr->fast_state.IncrementEpoch(); 1060 TraceAddEvent(thr, thr->fast_state, EventTypeFuncExit, 0); 1061 } 1062 1063 DCHECK_GT(thr->shadow_stack_pos, thr->shadow_stack); 1064 #if !SANITIZER_GO 1065 DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end); 1066 #endif 1067 thr->shadow_stack_pos--; 1068 } 1069 1070 void ThreadIgnoreBegin(ThreadState *thr, uptr pc) { 1071 DPrintf("#%d: ThreadIgnoreBegin\n", thr->tid); 1072 thr->ignore_reads_and_writes++; 1073 CHECK_GT(thr->ignore_reads_and_writes, 0); 1074 thr->fast_state.SetIgnoreBit(); 1075 #if !SANITIZER_GO 1076 if (pc && !ctx->after_multithreaded_fork) 1077 thr->mop_ignore_set.Add(CurrentStackId(thr, pc)); 1078 #endif 1079 } 1080 1081 void ThreadIgnoreEnd(ThreadState *thr) { 1082 DPrintf("#%d: ThreadIgnoreEnd\n", thr->tid); 1083 CHECK_GT(thr->ignore_reads_and_writes, 0); 1084 thr->ignore_reads_and_writes--; 1085 if (thr->ignore_reads_and_writes == 0) { 1086 thr->fast_state.ClearIgnoreBit(); 1087 #if !SANITIZER_GO 1088 thr->mop_ignore_set.Reset(); 1089 #endif 1090 } 1091 } 1092 1093 #if !SANITIZER_GO 1094 extern "C" SANITIZER_INTERFACE_ATTRIBUTE 1095 uptr __tsan_testonly_shadow_stack_current_size() { 1096 ThreadState *thr = cur_thread(); 1097 return thr->shadow_stack_pos - thr->shadow_stack; 1098 } 1099 #endif 1100 1101 void ThreadIgnoreSyncBegin(ThreadState *thr, uptr pc) { 1102 DPrintf("#%d: ThreadIgnoreSyncBegin\n", thr->tid); 1103 thr->ignore_sync++; 1104 CHECK_GT(thr->ignore_sync, 0); 1105 #if !SANITIZER_GO 1106 if (pc && !ctx->after_multithreaded_fork) 1107 thr->sync_ignore_set.Add(CurrentStackId(thr, pc)); 1108 #endif 1109 } 1110 1111 void ThreadIgnoreSyncEnd(ThreadState *thr) { 1112 DPrintf("#%d: ThreadIgnoreSyncEnd\n", thr->tid); 1113 CHECK_GT(thr->ignore_sync, 0); 1114 thr->ignore_sync--; 1115 #if !SANITIZER_GO 1116 if (thr->ignore_sync == 0) 1117 thr->sync_ignore_set.Reset(); 1118 #endif 1119 } 1120 1121 bool MD5Hash::operator==(const MD5Hash &other) const { 1122 return hash[0] == other.hash[0] && hash[1] == other.hash[1]; 1123 } 1124 1125 #if SANITIZER_DEBUG 1126 void build_consistency_debug() {} 1127 #else 1128 void build_consistency_release() {} 1129 #endif 1130 1131 } // namespace __tsan 1132 1133 #if SANITIZER_CHECK_DEADLOCKS 1134 namespace __sanitizer { 1135 using namespace __tsan; 1136 MutexMeta mutex_meta[] = { 1137 {MutexInvalid, "Invalid", {}}, 1138 {MutexThreadRegistry, "ThreadRegistry", {}}, 1139 {MutexTypeTrace, "Trace", {MutexLeaf}}, 1140 {MutexTypeReport, "Report", {MutexTypeSyncVar}}, 1141 {MutexTypeSyncVar, "SyncVar", {}}, 1142 {MutexTypeAnnotations, "Annotations", {}}, 1143 {MutexTypeAtExit, "AtExit", {MutexTypeSyncVar}}, 1144 {MutexTypeFired, "Fired", {MutexLeaf}}, 1145 {MutexTypeRacy, "Racy", {MutexLeaf}}, 1146 {MutexTypeGlobalProc, "GlobalProc", {}}, 1147 {}, 1148 }; 1149 1150 void PrintMutexPC(uptr pc) { StackTrace(&pc, 1).Print(); } 1151 } // namespace __sanitizer 1152 #endif 1153 1154 #if !SANITIZER_GO 1155 // Must be included in this file to make sure everything is inlined. 1156 # include "tsan_interface_inl.h" 1157 #endif 1158