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