1 1.1 mrg //===-- tsan_rtl.cpp ------------------------------------------------------===// 2 1.1 mrg // 3 1.1 mrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 mrg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 mrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 mrg // 7 1.1 mrg //===----------------------------------------------------------------------===// 8 1.1 mrg // 9 1.1 mrg // This file is a part of ThreadSanitizer (TSan), a race detector. 10 1.1 mrg // 11 1.1 mrg // Main file (entry points) for the TSan run-time. 12 1.1 mrg //===----------------------------------------------------------------------===// 13 1.1 mrg 14 1.3 mrg #include "tsan_rtl.h" 15 1.3 mrg 16 1.1 mrg #include "sanitizer_common/sanitizer_atomic.h" 17 1.1 mrg #include "sanitizer_common/sanitizer_common.h" 18 1.1 mrg #include "sanitizer_common/sanitizer_file.h" 19 1.5 mrg #include "sanitizer_common/sanitizer_interface_internal.h" 20 1.1 mrg #include "sanitizer_common/sanitizer_libc.h" 21 1.3 mrg #include "sanitizer_common/sanitizer_placement_new.h" 22 1.1 mrg #include "sanitizer_common/sanitizer_stackdepot.h" 23 1.1 mrg #include "sanitizer_common/sanitizer_symbolizer.h" 24 1.1 mrg #include "tsan_defs.h" 25 1.3 mrg #include "tsan_interface.h" 26 1.3 mrg #include "tsan_mman.h" 27 1.1 mrg #include "tsan_platform.h" 28 1.1 mrg #include "tsan_suppressions.h" 29 1.1 mrg #include "tsan_symbolize.h" 30 1.1 mrg #include "ubsan/ubsan_init.h" 31 1.1 mrg 32 1.1 mrg volatile int __tsan_resumed = 0; 33 1.1 mrg 34 1.1 mrg extern "C" void __tsan_resume() { 35 1.1 mrg __tsan_resumed = 1; 36 1.1 mrg } 37 1.1 mrg 38 1.5 mrg SANITIZER_WEAK_DEFAULT_IMPL 39 1.5 mrg void __tsan_test_only_on_fork() {} 40 1.5 mrg 41 1.1 mrg namespace __tsan { 42 1.1 mrg 43 1.3 mrg #if !SANITIZER_GO 44 1.3 mrg void (*on_initialize)(void); 45 1.3 mrg int (*on_finalize)(int); 46 1.3 mrg #endif 47 1.3 mrg 48 1.4 riastrad // XXX PR lib/58349 (https://gnats.NetBSD.org/58349): NetBSD ld.elf_so 49 1.4 riastrad // doesn't support TLS alignment beyond void *, so we have to buffer 50 1.4 riastrad // some extra space and do the alignment ourselves at all the reference 51 1.4 riastrad // sites. 52 1.5 mrg #if !SANITIZER_GO && !SANITIZER_APPLE 53 1.1 mrg __attribute__((tls_model("initial-exec"))) 54 1.4 riastrad THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState) + SANITIZER_CACHE_LINE_SIZE - 1] ALIGNED( 55 1.3 mrg SANITIZER_CACHE_LINE_SIZE); 56 1.1 mrg #endif 57 1.4 riastrad static char ctx_placeholder[sizeof(Context) + SANITIZER_CACHE_LINE_SIZE - 1] ALIGNED(SANITIZER_CACHE_LINE_SIZE); 58 1.1 mrg Context *ctx; 59 1.1 mrg 60 1.1 mrg // Can be overriden by a front-end. 61 1.1 mrg #ifdef TSAN_EXTERNAL_HOOKS 62 1.1 mrg bool OnFinalize(bool failed); 63 1.1 mrg void OnInitialize(); 64 1.1 mrg #else 65 1.1 mrg SANITIZER_WEAK_CXX_DEFAULT_IMPL 66 1.1 mrg bool OnFinalize(bool failed) { 67 1.5 mrg # if !SANITIZER_GO 68 1.3 mrg if (on_finalize) 69 1.3 mrg return on_finalize(failed); 70 1.5 mrg # endif 71 1.1 mrg return failed; 72 1.1 mrg } 73 1.5 mrg 74 1.1 mrg SANITIZER_WEAK_CXX_DEFAULT_IMPL 75 1.3 mrg void OnInitialize() { 76 1.5 mrg # if !SANITIZER_GO 77 1.3 mrg if (on_initialize) 78 1.3 mrg on_initialize(); 79 1.5 mrg # endif 80 1.5 mrg } 81 1.3 mrg #endif 82 1.5 mrg 83 1.5 mrg static TracePart* TracePartAlloc(ThreadState* thr) { 84 1.5 mrg TracePart* part = nullptr; 85 1.5 mrg { 86 1.5 mrg Lock lock(&ctx->slot_mtx); 87 1.5 mrg uptr max_parts = Trace::kMinParts + flags()->history_size; 88 1.5 mrg Trace* trace = &thr->tctx->trace; 89 1.5 mrg if (trace->parts_allocated == max_parts || 90 1.5 mrg ctx->trace_part_finished_excess) { 91 1.5 mrg part = ctx->trace_part_recycle.PopFront(); 92 1.5 mrg DPrintf("#%d: TracePartAlloc: part=%p\n", thr->tid, part); 93 1.5 mrg if (part && part->trace) { 94 1.5 mrg Trace* trace1 = part->trace; 95 1.5 mrg Lock trace_lock(&trace1->mtx); 96 1.5 mrg part->trace = nullptr; 97 1.5 mrg TracePart* part1 = trace1->parts.PopFront(); 98 1.5 mrg CHECK_EQ(part, part1); 99 1.5 mrg if (trace1->parts_allocated > trace1->parts.Size()) { 100 1.5 mrg ctx->trace_part_finished_excess += 101 1.5 mrg trace1->parts_allocated - trace1->parts.Size(); 102 1.5 mrg trace1->parts_allocated = trace1->parts.Size(); 103 1.5 mrg } 104 1.5 mrg } 105 1.5 mrg } 106 1.5 mrg if (trace->parts_allocated < max_parts) { 107 1.5 mrg trace->parts_allocated++; 108 1.5 mrg if (ctx->trace_part_finished_excess) 109 1.5 mrg ctx->trace_part_finished_excess--; 110 1.5 mrg } 111 1.5 mrg if (!part) 112 1.5 mrg ctx->trace_part_total_allocated++; 113 1.5 mrg else if (ctx->trace_part_recycle_finished) 114 1.5 mrg ctx->trace_part_recycle_finished--; 115 1.5 mrg } 116 1.5 mrg if (!part) 117 1.5 mrg part = new (MmapOrDie(sizeof(*part), "TracePart")) TracePart(); 118 1.5 mrg return part; 119 1.5 mrg } 120 1.5 mrg 121 1.5 mrg static void TracePartFree(TracePart* part) SANITIZER_REQUIRES(ctx->slot_mtx) { 122 1.5 mrg DCHECK(part->trace); 123 1.5 mrg part->trace = nullptr; 124 1.5 mrg ctx->trace_part_recycle.PushFront(part); 125 1.5 mrg } 126 1.5 mrg 127 1.5 mrg void TraceResetForTesting() { 128 1.5 mrg Lock lock(&ctx->slot_mtx); 129 1.5 mrg while (auto* part = ctx->trace_part_recycle.PopFront()) { 130 1.5 mrg if (auto trace = part->trace) 131 1.5 mrg CHECK_EQ(trace->parts.PopFront(), part); 132 1.5 mrg UnmapOrDie(part, sizeof(*part)); 133 1.5 mrg } 134 1.5 mrg ctx->trace_part_total_allocated = 0; 135 1.5 mrg ctx->trace_part_recycle_finished = 0; 136 1.5 mrg ctx->trace_part_finished_excess = 0; 137 1.5 mrg } 138 1.5 mrg 139 1.5 mrg static void DoResetImpl(uptr epoch) { 140 1.5 mrg ThreadRegistryLock lock0(&ctx->thread_registry); 141 1.5 mrg Lock lock1(&ctx->slot_mtx); 142 1.5 mrg CHECK_EQ(ctx->global_epoch, epoch); 143 1.5 mrg ctx->global_epoch++; 144 1.5 mrg CHECK(!ctx->resetting); 145 1.5 mrg ctx->resetting = true; 146 1.5 mrg for (u32 i = ctx->thread_registry.NumThreadsLocked(); i--;) { 147 1.5 mrg ThreadContext* tctx = (ThreadContext*)ctx->thread_registry.GetThreadLocked( 148 1.5 mrg static_cast<Tid>(i)); 149 1.5 mrg // Potentially we could purge all ThreadStatusDead threads from the 150 1.5 mrg // registry. Since we reset all shadow, they can't race with anything 151 1.5 mrg // anymore. However, their tid's can still be stored in some aux places 152 1.5 mrg // (e.g. tid of thread that created something). 153 1.5 mrg auto trace = &tctx->trace; 154 1.5 mrg Lock lock(&trace->mtx); 155 1.5 mrg bool attached = tctx->thr && tctx->thr->slot; 156 1.5 mrg auto parts = &trace->parts; 157 1.5 mrg bool local = false; 158 1.5 mrg while (!parts->Empty()) { 159 1.5 mrg auto part = parts->Front(); 160 1.5 mrg local = local || part == trace->local_head; 161 1.5 mrg if (local) 162 1.5 mrg CHECK(!ctx->trace_part_recycle.Queued(part)); 163 1.5 mrg else 164 1.5 mrg ctx->trace_part_recycle.Remove(part); 165 1.5 mrg if (attached && parts->Size() == 1) { 166 1.5 mrg // The thread is running and this is the last/current part. 167 1.5 mrg // Set the trace position to the end of the current part 168 1.5 mrg // to force the thread to call SwitchTracePart and re-attach 169 1.5 mrg // to a new slot and allocate a new trace part. 170 1.5 mrg // Note: the thread is concurrently modifying the position as well, 171 1.5 mrg // so this is only best-effort. The thread can only modify position 172 1.5 mrg // within this part, because switching parts is protected by 173 1.5 mrg // slot/trace mutexes that we hold here. 174 1.5 mrg atomic_store_relaxed( 175 1.5 mrg &tctx->thr->trace_pos, 176 1.5 mrg reinterpret_cast<uptr>(&part->events[TracePart::kSize])); 177 1.5 mrg break; 178 1.5 mrg } 179 1.5 mrg parts->Remove(part); 180 1.5 mrg TracePartFree(part); 181 1.5 mrg } 182 1.5 mrg CHECK_LE(parts->Size(), 1); 183 1.5 mrg trace->local_head = parts->Front(); 184 1.5 mrg if (tctx->thr && !tctx->thr->slot) { 185 1.5 mrg atomic_store_relaxed(&tctx->thr->trace_pos, 0); 186 1.5 mrg tctx->thr->trace_prev_pc = 0; 187 1.5 mrg } 188 1.5 mrg if (trace->parts_allocated > trace->parts.Size()) { 189 1.5 mrg ctx->trace_part_finished_excess += 190 1.5 mrg trace->parts_allocated - trace->parts.Size(); 191 1.5 mrg trace->parts_allocated = trace->parts.Size(); 192 1.5 mrg } 193 1.5 mrg } 194 1.5 mrg while (ctx->slot_queue.PopFront()) { 195 1.5 mrg } 196 1.5 mrg for (auto& slot : ctx->slots) { 197 1.5 mrg slot.SetEpoch(kEpochZero); 198 1.5 mrg slot.journal.Reset(); 199 1.5 mrg slot.thr = nullptr; 200 1.5 mrg ctx->slot_queue.PushBack(&slot); 201 1.5 mrg } 202 1.5 mrg 203 1.5 mrg DPrintf("Resetting shadow...\n"); 204 1.5 mrg auto shadow_begin = ShadowBeg(); 205 1.5 mrg auto shadow_end = ShadowEnd(); 206 1.5 mrg #if SANITIZER_GO 207 1.5 mrg CHECK_NE(0, ctx->mapped_shadow_begin); 208 1.5 mrg shadow_begin = ctx->mapped_shadow_begin; 209 1.5 mrg shadow_end = ctx->mapped_shadow_end; 210 1.5 mrg VPrintf(2, "shadow_begin-shadow_end: (0x%zx-0x%zx)\n", 211 1.5 mrg shadow_begin, shadow_end); 212 1.1 mrg #endif 213 1.1 mrg 214 1.5 mrg #if SANITIZER_WINDOWS 215 1.5 mrg auto resetFailed = 216 1.5 mrg !ZeroMmapFixedRegion(shadow_begin, shadow_end - shadow_begin); 217 1.5 mrg #else 218 1.5 mrg auto resetFailed = 219 1.5 mrg !MmapFixedSuperNoReserve(shadow_begin, shadow_end-shadow_begin, "shadow"); 220 1.5 mrg # if !SANITIZER_GO 221 1.5 mrg DontDumpShadow(shadow_begin, shadow_end - shadow_begin); 222 1.5 mrg # endif 223 1.5 mrg #endif 224 1.5 mrg if (resetFailed) { 225 1.5 mrg Printf("failed to reset shadow memory\n"); 226 1.5 mrg Die(); 227 1.5 mrg } 228 1.5 mrg DPrintf("Resetting meta shadow...\n"); 229 1.5 mrg ctx->metamap.ResetClocks(); 230 1.5 mrg StoreShadow(&ctx->last_spurious_race, Shadow::kEmpty); 231 1.5 mrg ctx->resetting = false; 232 1.5 mrg } 233 1.5 mrg 234 1.5 mrg // Clang does not understand locking all slots in the loop: 235 1.5 mrg // error: expecting mutex 'slot.mtx' to be held at start of each loop 236 1.5 mrg void DoReset(ThreadState* thr, uptr epoch) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { 237 1.5 mrg for (auto& slot : ctx->slots) { 238 1.5 mrg slot.mtx.Lock(); 239 1.5 mrg if (UNLIKELY(epoch == 0)) 240 1.5 mrg epoch = ctx->global_epoch; 241 1.5 mrg if (UNLIKELY(epoch != ctx->global_epoch)) { 242 1.5 mrg // Epoch can't change once we've locked the first slot. 243 1.5 mrg CHECK_EQ(slot.sid, 0); 244 1.5 mrg slot.mtx.Unlock(); 245 1.5 mrg return; 246 1.3 mrg } 247 1.3 mrg } 248 1.5 mrg DPrintf("#%d: DoReset epoch=%lu\n", thr ? thr->tid : -1, epoch); 249 1.5 mrg DoResetImpl(epoch); 250 1.5 mrg for (auto& slot : ctx->slots) slot.mtx.Unlock(); 251 1.5 mrg } 252 1.5 mrg 253 1.5 mrg void FlushShadowMemory() { DoReset(nullptr, 0); } 254 1.5 mrg 255 1.5 mrg static TidSlot* FindSlotAndLock(ThreadState* thr) 256 1.5 mrg SANITIZER_ACQUIRE(thr->slot->mtx) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { 257 1.5 mrg CHECK(!thr->slot); 258 1.5 mrg TidSlot* slot = nullptr; 259 1.5 mrg for (;;) { 260 1.5 mrg uptr epoch; 261 1.5 mrg { 262 1.5 mrg Lock lock(&ctx->slot_mtx); 263 1.5 mrg epoch = ctx->global_epoch; 264 1.5 mrg if (slot) { 265 1.5 mrg // This is an exhausted slot from the previous iteration. 266 1.5 mrg if (ctx->slot_queue.Queued(slot)) 267 1.5 mrg ctx->slot_queue.Remove(slot); 268 1.5 mrg thr->slot_locked = false; 269 1.5 mrg slot->mtx.Unlock(); 270 1.5 mrg } 271 1.5 mrg for (;;) { 272 1.5 mrg slot = ctx->slot_queue.PopFront(); 273 1.5 mrg if (!slot) 274 1.5 mrg break; 275 1.5 mrg if (slot->epoch() != kEpochLast) { 276 1.5 mrg ctx->slot_queue.PushBack(slot); 277 1.5 mrg break; 278 1.5 mrg } 279 1.5 mrg } 280 1.5 mrg } 281 1.5 mrg if (!slot) { 282 1.5 mrg DoReset(thr, epoch); 283 1.5 mrg continue; 284 1.5 mrg } 285 1.5 mrg slot->mtx.Lock(); 286 1.5 mrg CHECK(!thr->slot_locked); 287 1.5 mrg thr->slot_locked = true; 288 1.5 mrg if (slot->thr) { 289 1.5 mrg DPrintf("#%d: preempting sid=%d tid=%d\n", thr->tid, (u32)slot->sid, 290 1.5 mrg slot->thr->tid); 291 1.5 mrg slot->SetEpoch(slot->thr->fast_state.epoch()); 292 1.5 mrg slot->thr = nullptr; 293 1.5 mrg } 294 1.5 mrg if (slot->epoch() != kEpochLast) 295 1.5 mrg return slot; 296 1.5 mrg } 297 1.1 mrg } 298 1.1 mrg 299 1.5 mrg void SlotAttachAndLock(ThreadState* thr) { 300 1.5 mrg TidSlot* slot = FindSlotAndLock(thr); 301 1.5 mrg DPrintf("#%d: SlotAttach: slot=%u\n", thr->tid, static_cast<int>(slot->sid)); 302 1.5 mrg CHECK(!slot->thr); 303 1.5 mrg CHECK(!thr->slot); 304 1.5 mrg slot->thr = thr; 305 1.5 mrg thr->slot = slot; 306 1.5 mrg Epoch epoch = EpochInc(slot->epoch()); 307 1.5 mrg CHECK(!EpochOverflow(epoch)); 308 1.5 mrg slot->SetEpoch(epoch); 309 1.5 mrg thr->fast_state.SetSid(slot->sid); 310 1.5 mrg thr->fast_state.SetEpoch(epoch); 311 1.5 mrg if (thr->slot_epoch != ctx->global_epoch) { 312 1.5 mrg thr->slot_epoch = ctx->global_epoch; 313 1.5 mrg thr->clock.Reset(); 314 1.1 mrg #if !SANITIZER_GO 315 1.5 mrg thr->last_sleep_stack_id = kInvalidStackID; 316 1.5 mrg thr->last_sleep_clock.Reset(); 317 1.1 mrg #endif 318 1.5 mrg } 319 1.5 mrg thr->clock.Set(slot->sid, epoch); 320 1.5 mrg slot->journal.PushBack({thr->tid, epoch}); 321 1.5 mrg } 322 1.5 mrg 323 1.5 mrg static void SlotDetachImpl(ThreadState* thr, bool exiting) { 324 1.5 mrg TidSlot* slot = thr->slot; 325 1.5 mrg thr->slot = nullptr; 326 1.5 mrg if (thr != slot->thr) { 327 1.5 mrg slot = nullptr; // we don't own the slot anymore 328 1.5 mrg if (thr->slot_epoch != ctx->global_epoch) { 329 1.5 mrg TracePart* part = nullptr; 330 1.5 mrg auto* trace = &thr->tctx->trace; 331 1.5 mrg { 332 1.5 mrg Lock l(&trace->mtx); 333 1.5 mrg auto* parts = &trace->parts; 334 1.5 mrg // The trace can be completely empty in an unlikely event 335 1.5 mrg // the thread is preempted right after it acquired the slot 336 1.5 mrg // in ThreadStart and did not trace any events yet. 337 1.5 mrg CHECK_LE(parts->Size(), 1); 338 1.5 mrg part = parts->PopFront(); 339 1.5 mrg thr->tctx->trace.local_head = nullptr; 340 1.5 mrg atomic_store_relaxed(&thr->trace_pos, 0); 341 1.5 mrg thr->trace_prev_pc = 0; 342 1.5 mrg } 343 1.5 mrg if (part) { 344 1.5 mrg Lock l(&ctx->slot_mtx); 345 1.5 mrg TracePartFree(part); 346 1.5 mrg } 347 1.5 mrg } 348 1.5 mrg return; 349 1.5 mrg } 350 1.5 mrg CHECK(exiting || thr->fast_state.epoch() == kEpochLast); 351 1.5 mrg slot->SetEpoch(thr->fast_state.epoch()); 352 1.5 mrg slot->thr = nullptr; 353 1.5 mrg } 354 1.5 mrg 355 1.5 mrg void SlotDetach(ThreadState* thr) { 356 1.5 mrg Lock lock(&thr->slot->mtx); 357 1.5 mrg SlotDetachImpl(thr, true); 358 1.5 mrg } 359 1.5 mrg 360 1.5 mrg void SlotLock(ThreadState* thr) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { 361 1.5 mrg DCHECK(!thr->slot_locked); 362 1.5 mrg #if SANITIZER_DEBUG 363 1.5 mrg // Check these mutexes are not locked. 364 1.5 mrg // We can call DoReset from SlotAttachAndLock, which will lock 365 1.5 mrg // these mutexes, but it happens only every once in a while. 366 1.5 mrg { ThreadRegistryLock lock(&ctx->thread_registry); } 367 1.5 mrg { Lock lock(&ctx->slot_mtx); } 368 1.5 mrg #endif 369 1.5 mrg TidSlot* slot = thr->slot; 370 1.5 mrg slot->mtx.Lock(); 371 1.5 mrg thr->slot_locked = true; 372 1.5 mrg if (LIKELY(thr == slot->thr && thr->fast_state.epoch() != kEpochLast)) 373 1.5 mrg return; 374 1.5 mrg SlotDetachImpl(thr, false); 375 1.5 mrg thr->slot_locked = false; 376 1.5 mrg slot->mtx.Unlock(); 377 1.5 mrg SlotAttachAndLock(thr); 378 1.5 mrg } 379 1.5 mrg 380 1.5 mrg void SlotUnlock(ThreadState* thr) { 381 1.5 mrg DCHECK(thr->slot_locked); 382 1.5 mrg thr->slot_locked = false; 383 1.5 mrg thr->slot->mtx.Unlock(); 384 1.5 mrg } 385 1.1 mrg 386 1.1 mrg Context::Context() 387 1.3 mrg : initialized(), 388 1.3 mrg report_mtx(MutexTypeReport), 389 1.3 mrg nreported(), 390 1.5 mrg thread_registry([](Tid tid) -> ThreadContextBase* { 391 1.5 mrg return new (Alloc(sizeof(ThreadContext))) ThreadContext(tid); 392 1.5 mrg }), 393 1.3 mrg racy_mtx(MutexTypeRacy), 394 1.3 mrg racy_stacks(), 395 1.3 mrg fired_suppressions_mtx(MutexTypeFired), 396 1.5 mrg slot_mtx(MutexTypeSlots), 397 1.5 mrg resetting() { 398 1.1 mrg fired_suppressions.reserve(8); 399 1.5 mrg for (uptr i = 0; i < ARRAY_SIZE(slots); i++) { 400 1.5 mrg TidSlot* slot = &slots[i]; 401 1.5 mrg slot->sid = static_cast<Sid>(i); 402 1.5 mrg slot_queue.PushBack(slot); 403 1.5 mrg } 404 1.5 mrg global_epoch = 1; 405 1.1 mrg } 406 1.1 mrg 407 1.5 mrg TidSlot::TidSlot() : mtx(MutexTypeSlot) {} 408 1.5 mrg 409 1.1 mrg // The objects are allocated in TLS, so one may rely on zero-initialization. 410 1.5 mrg ThreadState::ThreadState(Tid tid) 411 1.5 mrg // Do not touch these, rely on zero initialization, 412 1.5 mrg // they may be accessed before the ctor. 413 1.5 mrg // ignore_reads_and_writes() 414 1.5 mrg // ignore_interceptors() 415 1.5 mrg : tid(tid) { 416 1.3 mrg CHECK_EQ(reinterpret_cast<uptr>(this) % SANITIZER_CACHE_LINE_SIZE, 0); 417 1.3 mrg #if !SANITIZER_GO 418 1.5 mrg // C/C++ uses fixed size shadow stack. 419 1.5 mrg const int kInitStackSize = kShadowStackSize; 420 1.5 mrg shadow_stack = static_cast<uptr*>( 421 1.5 mrg MmapNoReserveOrDie(kInitStackSize * sizeof(uptr), "shadow stack")); 422 1.5 mrg SetShadowRegionHugePageMode(reinterpret_cast<uptr>(shadow_stack), 423 1.5 mrg kInitStackSize * sizeof(uptr)); 424 1.3 mrg #else 425 1.5 mrg // Go uses malloc-allocated shadow stack with dynamic size. 426 1.3 mrg const int kInitStackSize = 8; 427 1.5 mrg shadow_stack = static_cast<uptr*>(Alloc(kInitStackSize * sizeof(uptr))); 428 1.5 mrg #endif 429 1.3 mrg shadow_stack_pos = shadow_stack; 430 1.3 mrg shadow_stack_end = shadow_stack + kInitStackSize; 431 1.1 mrg } 432 1.1 mrg 433 1.1 mrg #if !SANITIZER_GO 434 1.3 mrg void MemoryProfiler(u64 uptime) { 435 1.3 mrg if (ctx->memprof_fd == kInvalidFd) 436 1.3 mrg return; 437 1.1 mrg InternalMmapVector<char> buf(4096); 438 1.3 mrg WriteMemoryProfile(buf.data(), buf.size(), uptime); 439 1.3 mrg WriteToFile(ctx->memprof_fd, buf.data(), internal_strlen(buf.data())); 440 1.1 mrg } 441 1.1 mrg 442 1.5 mrg static bool InitializeMemoryProfiler() { 443 1.3 mrg ctx->memprof_fd = kInvalidFd; 444 1.3 mrg const char *fname = flags()->profile_memory; 445 1.3 mrg if (!fname || !fname[0]) 446 1.5 mrg return false; 447 1.3 mrg if (internal_strcmp(fname, "stdout") == 0) { 448 1.3 mrg ctx->memprof_fd = 1; 449 1.3 mrg } else if (internal_strcmp(fname, "stderr") == 0) { 450 1.3 mrg ctx->memprof_fd = 2; 451 1.3 mrg } else { 452 1.3 mrg InternalScopedString filename; 453 1.5 mrg filename.AppendF("%s.%d", fname, (int)internal_getpid()); 454 1.3 mrg ctx->memprof_fd = OpenFile(filename.data(), WrOnly); 455 1.3 mrg if (ctx->memprof_fd == kInvalidFd) { 456 1.3 mrg Printf("ThreadSanitizer: failed to open memory profile file '%s'\n", 457 1.3 mrg filename.data()); 458 1.5 mrg return false; 459 1.3 mrg } 460 1.3 mrg } 461 1.3 mrg MemoryProfiler(0); 462 1.5 mrg return true; 463 1.3 mrg } 464 1.3 mrg 465 1.3 mrg static void *BackgroundThread(void *arg) { 466 1.1 mrg // This is a non-initialized non-user thread, nothing to see here. 467 1.1 mrg // We don't use ScopedIgnoreInterceptors, because we want ignores to be 468 1.1 mrg // enabled even when the thread function exits (e.g. during pthread thread 469 1.1 mrg // shutdown code). 470 1.3 mrg cur_thread_init()->ignore_interceptors++; 471 1.1 mrg const u64 kMs2Ns = 1000 * 1000; 472 1.3 mrg const u64 start = NanoTime(); 473 1.1 mrg 474 1.5 mrg u64 last_flush = start; 475 1.1 mrg uptr last_rss = 0; 476 1.5 mrg while (!atomic_load_relaxed(&ctx->stop_background_thread)) { 477 1.1 mrg SleepForMillis(100); 478 1.1 mrg u64 now = NanoTime(); 479 1.1 mrg 480 1.1 mrg // Flush memory if requested. 481 1.1 mrg if (flags()->flush_memory_ms > 0) { 482 1.1 mrg if (last_flush + flags()->flush_memory_ms * kMs2Ns < now) { 483 1.5 mrg VReport(1, "ThreadSanitizer: periodic memory flush\n"); 484 1.1 mrg FlushShadowMemory(); 485 1.5 mrg now = last_flush = NanoTime(); 486 1.1 mrg } 487 1.1 mrg } 488 1.1 mrg if (flags()->memory_limit_mb > 0) { 489 1.1 mrg uptr rss = GetRSS(); 490 1.1 mrg uptr limit = uptr(flags()->memory_limit_mb) << 20; 491 1.5 mrg VReport(1, 492 1.5 mrg "ThreadSanitizer: memory flush check" 493 1.5 mrg " RSS=%llu LAST=%llu LIMIT=%llu\n", 494 1.1 mrg (u64)rss >> 20, (u64)last_rss >> 20, (u64)limit >> 20); 495 1.1 mrg if (2 * rss > limit + last_rss) { 496 1.5 mrg VReport(1, "ThreadSanitizer: flushing memory due to RSS\n"); 497 1.1 mrg FlushShadowMemory(); 498 1.1 mrg rss = GetRSS(); 499 1.5 mrg now = NanoTime(); 500 1.5 mrg VReport(1, "ThreadSanitizer: memory flushed RSS=%llu\n", 501 1.5 mrg (u64)rss >> 20); 502 1.1 mrg } 503 1.1 mrg last_rss = rss; 504 1.1 mrg } 505 1.1 mrg 506 1.3 mrg MemoryProfiler(now - start); 507 1.1 mrg 508 1.1 mrg // Flush symbolizer cache if requested. 509 1.1 mrg if (flags()->flush_symbolizer_ms > 0) { 510 1.1 mrg u64 last = atomic_load(&ctx->last_symbolize_time_ns, 511 1.1 mrg memory_order_relaxed); 512 1.1 mrg if (last != 0 && last + flags()->flush_symbolizer_ms * kMs2Ns < now) { 513 1.1 mrg Lock l(&ctx->report_mtx); 514 1.1 mrg ScopedErrorReportLock l2; 515 1.1 mrg SymbolizeFlush(); 516 1.1 mrg atomic_store(&ctx->last_symbolize_time_ns, 0, memory_order_relaxed); 517 1.1 mrg } 518 1.1 mrg } 519 1.1 mrg } 520 1.3 mrg return nullptr; 521 1.1 mrg } 522 1.1 mrg 523 1.1 mrg static void StartBackgroundThread() { 524 1.1 mrg ctx->background_thread = internal_start_thread(&BackgroundThread, 0); 525 1.1 mrg } 526 1.1 mrg 527 1.1 mrg #ifndef __mips__ 528 1.1 mrg static void StopBackgroundThread() { 529 1.1 mrg atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed); 530 1.1 mrg internal_join_thread(ctx->background_thread); 531 1.1 mrg ctx->background_thread = 0; 532 1.1 mrg } 533 1.1 mrg #endif 534 1.1 mrg #endif 535 1.1 mrg 536 1.1 mrg void DontNeedShadowFor(uptr addr, uptr size) { 537 1.3 mrg ReleaseMemoryPagesToOS(reinterpret_cast<uptr>(MemToShadow(addr)), 538 1.3 mrg reinterpret_cast<uptr>(MemToShadow(addr + size))); 539 1.1 mrg } 540 1.1 mrg 541 1.1 mrg #if !SANITIZER_GO 542 1.5 mrg // We call UnmapShadow before the actual munmap, at that point we don't yet 543 1.5 mrg // know if the provided address/size are sane. We can't call UnmapShadow 544 1.5 mrg // after the actual munmap becuase at that point the memory range can 545 1.5 mrg // already be reused for something else, so we can't rely on the munmap 546 1.5 mrg // return value to understand is the values are sane. 547 1.5 mrg // While calling munmap with insane values (non-canonical address, negative 548 1.5 mrg // size, etc) is an error, the kernel won't crash. We must also try to not 549 1.5 mrg // crash as the failure mode is very confusing (paging fault inside of the 550 1.5 mrg // runtime on some derived shadow address). 551 1.5 mrg static bool IsValidMmapRange(uptr addr, uptr size) { 552 1.5 mrg if (size == 0) 553 1.5 mrg return true; 554 1.5 mrg if (static_cast<sptr>(size) < 0) 555 1.5 mrg return false; 556 1.5 mrg if (!IsAppMem(addr) || !IsAppMem(addr + size - 1)) 557 1.5 mrg return false; 558 1.5 mrg // Check that if the start of the region belongs to one of app ranges, 559 1.5 mrg // end of the region belongs to the same region. 560 1.5 mrg const uptr ranges[][2] = { 561 1.5 mrg {LoAppMemBeg(), LoAppMemEnd()}, 562 1.5 mrg {MidAppMemBeg(), MidAppMemEnd()}, 563 1.5 mrg {HiAppMemBeg(), HiAppMemEnd()}, 564 1.5 mrg }; 565 1.5 mrg for (auto range : ranges) { 566 1.5 mrg if (addr >= range[0] && addr < range[1]) 567 1.5 mrg return addr + size <= range[1]; 568 1.5 mrg } 569 1.5 mrg return false; 570 1.5 mrg } 571 1.5 mrg 572 1.1 mrg void UnmapShadow(ThreadState *thr, uptr addr, uptr size) { 573 1.5 mrg if (size == 0 || !IsValidMmapRange(addr, size)) 574 1.5 mrg return; 575 1.1 mrg DontNeedShadowFor(addr, size); 576 1.1 mrg ScopedGlobalProcessor sgp; 577 1.5 mrg SlotLocker locker(thr, true); 578 1.5 mrg ctx->metamap.ResetRange(thr->proc(), addr, size, true); 579 1.1 mrg } 580 1.1 mrg #endif 581 1.1 mrg 582 1.1 mrg void MapShadow(uptr addr, uptr size) { 583 1.5 mrg // Ensure thead registry lock held, so as to synchronize 584 1.5 mrg // with DoReset, which also access the mapped_shadow_* ctxt fields. 585 1.5 mrg ThreadRegistryLock lock0(&ctx->thread_registry); 586 1.5 mrg static bool data_mapped = false; 587 1.5 mrg 588 1.5 mrg #if !SANITIZER_GO 589 1.1 mrg // Global data is not 64K aligned, but there are no adjacent mappings, 590 1.1 mrg // so we can get away with unaligned mapping. 591 1.1 mrg // CHECK_EQ(addr, addr & ~((64 << 10) - 1)); // windows wants 64K alignment 592 1.1 mrg const uptr kPageSize = GetPageSizeCached(); 593 1.1 mrg uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), kPageSize); 594 1.1 mrg uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), kPageSize); 595 1.5 mrg if (!MmapFixedNoReserve(shadow_begin, shadow_end - shadow_begin, "shadow")) 596 1.1 mrg Die(); 597 1.5 mrg #else 598 1.5 mrg uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), (64 << 10)); 599 1.5 mrg uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), (64 << 10)); 600 1.5 mrg VPrintf(2, "MapShadow for (0x%zx-0x%zx), begin/end: (0x%zx-0x%zx)\n", 601 1.5 mrg addr, addr + size, shadow_begin, shadow_end); 602 1.5 mrg 603 1.5 mrg if (!data_mapped) { 604 1.5 mrg // First call maps data+bss. 605 1.5 mrg if (!MmapFixedSuperNoReserve(shadow_begin, shadow_end - shadow_begin, "shadow")) 606 1.5 mrg Die(); 607 1.5 mrg } else { 608 1.5 mrg VPrintf(2, "ctx->mapped_shadow_{begin,end} = (0x%zx-0x%zx)\n", 609 1.5 mrg ctx->mapped_shadow_begin, ctx->mapped_shadow_end); 610 1.5 mrg // Second and subsequent calls map heap. 611 1.5 mrg if (shadow_end <= ctx->mapped_shadow_end) 612 1.5 mrg return; 613 1.5 mrg if (!ctx->mapped_shadow_begin || ctx->mapped_shadow_begin > shadow_begin) 614 1.5 mrg ctx->mapped_shadow_begin = shadow_begin; 615 1.5 mrg if (shadow_begin < ctx->mapped_shadow_end) 616 1.5 mrg shadow_begin = ctx->mapped_shadow_end; 617 1.5 mrg VPrintf(2, "MapShadow begin/end = (0x%zx-0x%zx)\n", 618 1.5 mrg shadow_begin, shadow_end); 619 1.5 mrg if (!MmapFixedSuperNoReserve(shadow_begin, shadow_end - shadow_begin, 620 1.5 mrg "shadow")) 621 1.5 mrg Die(); 622 1.5 mrg ctx->mapped_shadow_end = shadow_end; 623 1.5 mrg } 624 1.5 mrg #endif 625 1.1 mrg 626 1.1 mrg // Meta shadow is 2:1, so tread carefully. 627 1.1 mrg static uptr mapped_meta_end = 0; 628 1.1 mrg uptr meta_begin = (uptr)MemToMeta(addr); 629 1.1 mrg uptr meta_end = (uptr)MemToMeta(addr + size); 630 1.1 mrg meta_begin = RoundDownTo(meta_begin, 64 << 10); 631 1.1 mrg meta_end = RoundUpTo(meta_end, 64 << 10); 632 1.1 mrg if (!data_mapped) { 633 1.1 mrg // First call maps data+bss. 634 1.1 mrg data_mapped = true; 635 1.3 mrg if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin, 636 1.3 mrg "meta shadow")) 637 1.1 mrg Die(); 638 1.1 mrg } else { 639 1.3 mrg // Mapping continuous heap. 640 1.1 mrg // Windows wants 64K alignment. 641 1.1 mrg meta_begin = RoundDownTo(meta_begin, 64 << 10); 642 1.1 mrg meta_end = RoundUpTo(meta_end, 64 << 10); 643 1.5 mrg CHECK_GT(meta_end, mapped_meta_end); 644 1.1 mrg if (meta_begin < mapped_meta_end) 645 1.1 mrg meta_begin = mapped_meta_end; 646 1.3 mrg if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin, 647 1.3 mrg "meta shadow")) 648 1.1 mrg Die(); 649 1.1 mrg mapped_meta_end = meta_end; 650 1.1 mrg } 651 1.3 mrg VPrintf(2, "mapped meta shadow for (0x%zx-0x%zx) at (0x%zx-0x%zx)\n", addr, 652 1.3 mrg addr + size, meta_begin, meta_end); 653 1.1 mrg } 654 1.1 mrg 655 1.1 mrg #if !SANITIZER_GO 656 1.1 mrg static void OnStackUnwind(const SignalContext &sig, const void *, 657 1.1 mrg BufferedStackTrace *stack) { 658 1.1 mrg stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, 659 1.1 mrg common_flags()->fast_unwind_on_fatal); 660 1.1 mrg } 661 1.1 mrg 662 1.1 mrg static void TsanOnDeadlySignal(int signo, void *siginfo, void *context) { 663 1.1 mrg HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr); 664 1.1 mrg } 665 1.1 mrg #endif 666 1.1 mrg 667 1.3 mrg void CheckUnwind() { 668 1.3 mrg // There is high probability that interceptors will check-fail as well, 669 1.3 mrg // on the other hand there is no sense in processing interceptors 670 1.3 mrg // since we are going to die soon. 671 1.3 mrg ScopedIgnoreInterceptors ignore; 672 1.3 mrg #if !SANITIZER_GO 673 1.5 mrg ThreadState* thr = cur_thread(); 674 1.5 mrg thr->nomalloc = false; 675 1.5 mrg thr->ignore_sync++; 676 1.5 mrg thr->ignore_reads_and_writes++; 677 1.5 mrg atomic_store_relaxed(&thr->in_signal_handler, 0); 678 1.3 mrg #endif 679 1.3 mrg PrintCurrentStackSlow(StackTrace::GetCurrentPc()); 680 1.3 mrg } 681 1.3 mrg 682 1.3 mrg bool is_initialized; 683 1.3 mrg 684 1.1 mrg void Initialize(ThreadState *thr) { 685 1.1 mrg // Thread safe because done before all threads exist. 686 1.1 mrg if (is_initialized) 687 1.1 mrg return; 688 1.1 mrg is_initialized = true; 689 1.1 mrg // We are not ready to handle interceptors yet. 690 1.1 mrg ScopedIgnoreInterceptors ignore; 691 1.1 mrg SanitizerToolName = "ThreadSanitizer"; 692 1.1 mrg // Install tool-specific callbacks in sanitizer_common. 693 1.3 mrg SetCheckUnwindCallback(CheckUnwind); 694 1.1 mrg 695 1.4 riastrad ctx = new(reinterpret_cast<char *>((reinterpret_cast<uptr>(ctx_placeholder) + SANITIZER_CACHE_LINE_SIZE - 1) & ~static_cast<uptr>(SANITIZER_CACHE_LINE_SIZE - 1))) Context; 696 1.1 mrg const char *env_name = SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS"; 697 1.1 mrg const char *options = GetEnv(env_name); 698 1.1 mrg CacheBinaryName(); 699 1.1 mrg CheckASLR(); 700 1.1 mrg InitializeFlags(&ctx->flags, options, env_name); 701 1.1 mrg AvoidCVE_2016_2143(); 702 1.1 mrg __sanitizer::InitializePlatformEarly(); 703 1.1 mrg __tsan::InitializePlatformEarly(); 704 1.1 mrg 705 1.1 mrg #if !SANITIZER_GO 706 1.1 mrg InitializeAllocator(); 707 1.1 mrg ReplaceSystemMalloc(); 708 1.1 mrg #endif 709 1.1 mrg if (common_flags()->detect_deadlocks) 710 1.1 mrg ctx->dd = DDetector::Create(flags()); 711 1.1 mrg Processor *proc = ProcCreate(); 712 1.1 mrg ProcWire(proc, thr); 713 1.1 mrg InitializeInterceptors(); 714 1.1 mrg InitializePlatform(); 715 1.1 mrg InitializeDynamicAnnotations(); 716 1.1 mrg #if !SANITIZER_GO 717 1.1 mrg InitializeShadowMemory(); 718 1.1 mrg InitializeAllocatorLate(); 719 1.1 mrg InstallDeadlySignalHandlers(TsanOnDeadlySignal); 720 1.1 mrg #endif 721 1.1 mrg // Setup correct file descriptor for error reports. 722 1.1 mrg __sanitizer_set_report_path(common_flags()->log_path); 723 1.1 mrg InitializeSuppressions(); 724 1.1 mrg #if !SANITIZER_GO 725 1.1 mrg InitializeLibIgnore(); 726 1.1 mrg Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer); 727 1.1 mrg #endif 728 1.1 mrg 729 1.5 mrg VPrintf(1, "***** Running under ThreadSanitizer v3 (pid %d) *****\n", 730 1.1 mrg (int)internal_getpid()); 731 1.1 mrg 732 1.1 mrg // Initialize thread 0. 733 1.5 mrg Tid tid = ThreadCreate(nullptr, 0, 0, true); 734 1.3 mrg CHECK_EQ(tid, kMainTid); 735 1.1 mrg ThreadStart(thr, tid, GetTid(), ThreadType::Regular); 736 1.1 mrg #if TSAN_CONTAINS_UBSAN 737 1.1 mrg __ubsan::InitAsPlugin(); 738 1.1 mrg #endif 739 1.1 mrg 740 1.1 mrg #if !SANITIZER_GO 741 1.1 mrg Symbolizer::LateInitialize(); 742 1.5 mrg if (InitializeMemoryProfiler() || flags()->force_background_thread) 743 1.5 mrg MaybeSpawnBackgroundThread(); 744 1.1 mrg #endif 745 1.5 mrg ctx->initialized = true; 746 1.1 mrg 747 1.1 mrg if (flags()->stop_on_start) { 748 1.1 mrg Printf("ThreadSanitizer is suspended at startup (pid %d)." 749 1.1 mrg " Call __tsan_resume().\n", 750 1.1 mrg (int)internal_getpid()); 751 1.1 mrg while (__tsan_resumed == 0) {} 752 1.1 mrg } 753 1.1 mrg 754 1.1 mrg OnInitialize(); 755 1.1 mrg } 756 1.1 mrg 757 1.1 mrg void MaybeSpawnBackgroundThread() { 758 1.1 mrg // On MIPS, TSan initialization is run before 759 1.1 mrg // __pthread_initialize_minimal_internal() is finished, so we can not spawn 760 1.1 mrg // new threads. 761 1.1 mrg #if !SANITIZER_GO && !defined(__mips__) 762 1.1 mrg static atomic_uint32_t bg_thread = {}; 763 1.1 mrg if (atomic_load(&bg_thread, memory_order_relaxed) == 0 && 764 1.1 mrg atomic_exchange(&bg_thread, 1, memory_order_relaxed) == 0) { 765 1.1 mrg StartBackgroundThread(); 766 1.1 mrg SetSandboxingCallback(StopBackgroundThread); 767 1.1 mrg } 768 1.1 mrg #endif 769 1.1 mrg } 770 1.1 mrg 771 1.1 mrg int Finalize(ThreadState *thr) { 772 1.1 mrg bool failed = false; 773 1.1 mrg 774 1.5 mrg #if !SANITIZER_GO 775 1.3 mrg if (common_flags()->print_module_map == 1) 776 1.3 mrg DumpProcessMap(); 777 1.5 mrg #endif 778 1.1 mrg 779 1.1 mrg if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1) 780 1.5 mrg internal_usleep(u64(flags()->atexit_sleep_ms) * 1000); 781 1.1 mrg 782 1.5 mrg { 783 1.5 mrg // Wait for pending reports. 784 1.5 mrg ScopedErrorReportLock lock; 785 1.5 mrg } 786 1.1 mrg 787 1.1 mrg #if !SANITIZER_GO 788 1.1 mrg if (Verbosity()) AllocatorPrintStats(); 789 1.1 mrg #endif 790 1.1 mrg 791 1.1 mrg ThreadFinalize(thr); 792 1.1 mrg 793 1.1 mrg if (ctx->nreported) { 794 1.1 mrg failed = true; 795 1.1 mrg #if !SANITIZER_GO 796 1.1 mrg Printf("ThreadSanitizer: reported %d warnings\n", ctx->nreported); 797 1.1 mrg #else 798 1.1 mrg Printf("Found %d data race(s)\n", ctx->nreported); 799 1.1 mrg #endif 800 1.1 mrg } 801 1.1 mrg 802 1.1 mrg if (common_flags()->print_suppressions) 803 1.1 mrg PrintMatchedSuppressions(); 804 1.1 mrg 805 1.1 mrg failed = OnFinalize(failed); 806 1.1 mrg 807 1.1 mrg return failed ? common_flags()->exitcode : 0; 808 1.1 mrg } 809 1.1 mrg 810 1.1 mrg #if !SANITIZER_GO 811 1.5 mrg void ForkBefore(ThreadState* thr, uptr pc) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { 812 1.5 mrg GlobalProcessorLock(); 813 1.5 mrg // Detaching from the slot makes OnUserFree skip writing to the shadow. 814 1.5 mrg // The slot will be locked so any attempts to use it will deadlock anyway. 815 1.5 mrg SlotDetach(thr); 816 1.5 mrg for (auto& slot : ctx->slots) slot.mtx.Lock(); 817 1.3 mrg ctx->thread_registry.Lock(); 818 1.5 mrg ctx->slot_mtx.Lock(); 819 1.3 mrg ScopedErrorReportLock::Lock(); 820 1.5 mrg AllocatorLock(); 821 1.3 mrg // Suppress all reports in the pthread_atfork callbacks. 822 1.3 mrg // Reports will deadlock on the report_mtx. 823 1.3 mrg // We could ignore sync operations as well, 824 1.3 mrg // but so far it's unclear if it will do more good or harm. 825 1.3 mrg // Unnecessarily ignoring things can lead to false positives later. 826 1.3 mrg thr->suppress_reports++; 827 1.3 mrg // On OS X, REAL(fork) can call intercepted functions (OSSpinLockLock), and 828 1.3 mrg // we'll assert in CheckNoLocks() unless we ignore interceptors. 829 1.5 mrg // On OS X libSystem_atfork_prepare/parent/child callbacks are called 830 1.5 mrg // after/before our callbacks and they call free. 831 1.3 mrg thr->ignore_interceptors++; 832 1.5 mrg // Disables memory write in OnUserAlloc/Free. 833 1.5 mrg thr->ignore_reads_and_writes++; 834 1.5 mrg 835 1.5 mrg __tsan_test_only_on_fork(); 836 1.3 mrg } 837 1.3 mrg 838 1.5 mrg static void ForkAfter(ThreadState* thr) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { 839 1.3 mrg thr->suppress_reports--; // Enabled in ForkBefore. 840 1.3 mrg thr->ignore_interceptors--; 841 1.5 mrg thr->ignore_reads_and_writes--; 842 1.5 mrg AllocatorUnlock(); 843 1.3 mrg ScopedErrorReportLock::Unlock(); 844 1.5 mrg ctx->slot_mtx.Unlock(); 845 1.3 mrg ctx->thread_registry.Unlock(); 846 1.5 mrg for (auto& slot : ctx->slots) slot.mtx.Unlock(); 847 1.5 mrg SlotAttachAndLock(thr); 848 1.5 mrg SlotUnlock(thr); 849 1.5 mrg GlobalProcessorUnlock(); 850 1.1 mrg } 851 1.1 mrg 852 1.5 mrg void ForkParentAfter(ThreadState* thr, uptr pc) { ForkAfter(thr); } 853 1.5 mrg 854 1.5 mrg void ForkChildAfter(ThreadState* thr, uptr pc, bool start_thread) { 855 1.5 mrg ForkAfter(thr); 856 1.5 mrg u32 nthread = ctx->thread_registry.OnFork(thr->tid); 857 1.5 mrg VPrintf(1, 858 1.5 mrg "ThreadSanitizer: forked new process with pid %d," 859 1.5 mrg " parent had %d threads\n", 860 1.5 mrg (int)internal_getpid(), (int)nthread); 861 1.1 mrg if (nthread == 1) { 862 1.3 mrg if (start_thread) 863 1.3 mrg StartBackgroundThread(); 864 1.1 mrg } else { 865 1.1 mrg // We've just forked a multi-threaded process. We cannot reasonably function 866 1.1 mrg // after that (some mutexes may be locked before fork). So just enable 867 1.1 mrg // ignores for everything in the hope that we will exec soon. 868 1.1 mrg ctx->after_multithreaded_fork = true; 869 1.1 mrg thr->ignore_interceptors++; 870 1.5 mrg thr->suppress_reports++; 871 1.1 mrg ThreadIgnoreBegin(thr, pc); 872 1.1 mrg ThreadIgnoreSyncBegin(thr, pc); 873 1.1 mrg } 874 1.1 mrg } 875 1.1 mrg #endif 876 1.1 mrg 877 1.1 mrg #if SANITIZER_GO 878 1.1 mrg NOINLINE 879 1.1 mrg void GrowShadowStack(ThreadState *thr) { 880 1.1 mrg const int sz = thr->shadow_stack_end - thr->shadow_stack; 881 1.1 mrg const int newsz = 2 * sz; 882 1.3 mrg auto *newstack = (uptr *)Alloc(newsz * sizeof(uptr)); 883 1.1 mrg internal_memcpy(newstack, thr->shadow_stack, sz * sizeof(uptr)); 884 1.3 mrg Free(thr->shadow_stack); 885 1.1 mrg thr->shadow_stack = newstack; 886 1.1 mrg thr->shadow_stack_pos = newstack + sz; 887 1.1 mrg thr->shadow_stack_end = newstack + newsz; 888 1.1 mrg } 889 1.1 mrg #endif 890 1.1 mrg 891 1.3 mrg StackID CurrentStackId(ThreadState *thr, uptr pc) { 892 1.5 mrg #if !SANITIZER_GO 893 1.1 mrg if (!thr->is_inited) // May happen during bootstrap. 894 1.3 mrg return kInvalidStackID; 895 1.5 mrg #endif 896 1.1 mrg if (pc != 0) { 897 1.1 mrg #if !SANITIZER_GO 898 1.1 mrg DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end); 899 1.1 mrg #else 900 1.1 mrg if (thr->shadow_stack_pos == thr->shadow_stack_end) 901 1.1 mrg GrowShadowStack(thr); 902 1.1 mrg #endif 903 1.1 mrg thr->shadow_stack_pos[0] = pc; 904 1.1 mrg thr->shadow_stack_pos++; 905 1.1 mrg } 906 1.3 mrg StackID id = StackDepotPut( 907 1.1 mrg StackTrace(thr->shadow_stack, thr->shadow_stack_pos - thr->shadow_stack)); 908 1.1 mrg if (pc != 0) 909 1.1 mrg thr->shadow_stack_pos--; 910 1.1 mrg return id; 911 1.1 mrg } 912 1.1 mrg 913 1.5 mrg static bool TraceSkipGap(ThreadState* thr) { 914 1.3 mrg Trace *trace = &thr->tctx->trace; 915 1.3 mrg Event *pos = reinterpret_cast<Event *>(atomic_load_relaxed(&thr->trace_pos)); 916 1.3 mrg DCHECK_EQ(reinterpret_cast<uptr>(pos + 1) & TracePart::kAlignment, 0); 917 1.3 mrg auto *part = trace->parts.Back(); 918 1.5 mrg DPrintf("#%d: TraceSwitchPart enter trace=%p parts=%p-%p pos=%p\n", thr->tid, 919 1.5 mrg trace, trace->parts.Front(), part, pos); 920 1.5 mrg if (!part) 921 1.5 mrg return false; 922 1.5 mrg // We can get here when we still have space in the current trace part. 923 1.5 mrg // The fast-path check in TraceAcquire has false positives in the middle of 924 1.5 mrg // the part. Check if we are indeed at the end of the current part or not, 925 1.5 mrg // and fill any gaps with NopEvent's. 926 1.5 mrg Event* end = &part->events[TracePart::kSize]; 927 1.5 mrg DCHECK_GE(pos, &part->events[0]); 928 1.5 mrg DCHECK_LE(pos, end); 929 1.5 mrg if (pos + 1 < end) { 930 1.5 mrg if ((reinterpret_cast<uptr>(pos) & TracePart::kAlignment) == 931 1.5 mrg TracePart::kAlignment) 932 1.3 mrg *pos++ = NopEvent; 933 1.5 mrg *pos++ = NopEvent; 934 1.5 mrg DCHECK_LE(pos + 2, end); 935 1.5 mrg atomic_store_relaxed(&thr->trace_pos, reinterpret_cast<uptr>(pos)); 936 1.5 mrg return true; 937 1.3 mrg } 938 1.5 mrg // We are indeed at the end. 939 1.5 mrg for (; pos < end; pos++) *pos = NopEvent; 940 1.5 mrg return false; 941 1.5 mrg } 942 1.5 mrg 943 1.5 mrg NOINLINE 944 1.5 mrg void TraceSwitchPart(ThreadState* thr) { 945 1.5 mrg if (TraceSkipGap(thr)) 946 1.5 mrg return; 947 1.3 mrg #if !SANITIZER_GO 948 1.3 mrg if (ctx->after_multithreaded_fork) { 949 1.3 mrg // We just need to survive till exec. 950 1.5 mrg TracePart* part = thr->tctx->trace.parts.Back(); 951 1.5 mrg if (part) { 952 1.5 mrg atomic_store_relaxed(&thr->trace_pos, 953 1.5 mrg reinterpret_cast<uptr>(&part->events[0])); 954 1.5 mrg return; 955 1.5 mrg } 956 1.3 mrg } 957 1.3 mrg #endif 958 1.5 mrg TraceSwitchPartImpl(thr); 959 1.5 mrg } 960 1.5 mrg 961 1.5 mrg void TraceSwitchPartImpl(ThreadState* thr) { 962 1.5 mrg SlotLocker locker(thr, true); 963 1.5 mrg Trace* trace = &thr->tctx->trace; 964 1.5 mrg TracePart* part = TracePartAlloc(thr); 965 1.3 mrg part->trace = trace; 966 1.3 mrg thr->trace_prev_pc = 0; 967 1.5 mrg TracePart* recycle = nullptr; 968 1.5 mrg // Keep roughly half of parts local to the thread 969 1.5 mrg // (not queued into the recycle queue). 970 1.5 mrg uptr local_parts = (Trace::kMinParts + flags()->history_size + 1) / 2; 971 1.3 mrg { 972 1.3 mrg Lock lock(&trace->mtx); 973 1.5 mrg if (trace->parts.Empty()) 974 1.5 mrg trace->local_head = part; 975 1.5 mrg if (trace->parts.Size() >= local_parts) { 976 1.5 mrg recycle = trace->local_head; 977 1.5 mrg trace->local_head = trace->parts.Next(recycle); 978 1.5 mrg } 979 1.3 mrg trace->parts.PushBack(part); 980 1.3 mrg atomic_store_relaxed(&thr->trace_pos, 981 1.3 mrg reinterpret_cast<uptr>(&part->events[0])); 982 1.3 mrg } 983 1.3 mrg // Make this part self-sufficient by restoring the current stack 984 1.3 mrg // and mutex set in the beginning of the trace. 985 1.3 mrg TraceTime(thr); 986 1.5 mrg { 987 1.5 mrg // Pathologically large stacks may not fit into the part. 988 1.5 mrg // In these cases we log only fixed number of top frames. 989 1.5 mrg const uptr kMaxFrames = 1000; 990 1.5 mrg // Check that kMaxFrames won't consume the whole part. 991 1.5 mrg static_assert(kMaxFrames < TracePart::kSize / 2, "kMaxFrames is too big"); 992 1.5 mrg uptr* pos = Max(&thr->shadow_stack[0], thr->shadow_stack_pos - kMaxFrames); 993 1.5 mrg for (; pos < thr->shadow_stack_pos; pos++) { 994 1.5 mrg if (TryTraceFunc(thr, *pos)) 995 1.5 mrg continue; 996 1.5 mrg CHECK(TraceSkipGap(thr)); 997 1.5 mrg CHECK(TryTraceFunc(thr, *pos)); 998 1.5 mrg } 999 1.5 mrg } 1000 1.3 mrg for (uptr i = 0; i < thr->mset.Size(); i++) { 1001 1.3 mrg MutexSet::Desc d = thr->mset.Get(i); 1002 1.5 mrg for (uptr i = 0; i < d.count; i++) 1003 1.5 mrg TraceMutexLock(thr, d.write ? EventType::kLock : EventType::kRLock, 0, 1004 1.5 mrg d.addr, d.stack_id); 1005 1.5 mrg } 1006 1.5 mrg // Callers of TraceSwitchPart expect that TraceAcquire will always succeed 1007 1.5 mrg // after the call. It's possible that TryTraceFunc/TraceMutexLock above 1008 1.5 mrg // filled the trace part exactly up to the TracePart::kAlignment gap 1009 1.5 mrg // and the next TraceAcquire won't succeed. Skip the gap to avoid that. 1010 1.5 mrg EventFunc *ev; 1011 1.5 mrg if (!TraceAcquire(thr, &ev)) { 1012 1.5 mrg CHECK(TraceSkipGap(thr)); 1013 1.5 mrg CHECK(TraceAcquire(thr, &ev)); 1014 1.3 mrg } 1015 1.5 mrg { 1016 1.5 mrg Lock lock(&ctx->slot_mtx); 1017 1.5 mrg // There is a small chance that the slot may be not queued at this point. 1018 1.5 mrg // This can happen if the slot has kEpochLast epoch and another thread 1019 1.5 mrg // in FindSlotAndLock discovered that it's exhausted and removed it from 1020 1.5 mrg // the slot queue. kEpochLast can happen in 2 cases: (1) if TraceSwitchPart 1021 1.5 mrg // was called with the slot locked and epoch already at kEpochLast, 1022 1.5 mrg // or (2) if we've acquired a new slot in SlotLock in the beginning 1023 1.5 mrg // of the function and the slot was at kEpochLast - 1, so after increment 1024 1.5 mrg // in SlotAttachAndLock it become kEpochLast. 1025 1.5 mrg if (ctx->slot_queue.Queued(thr->slot)) { 1026 1.5 mrg ctx->slot_queue.Remove(thr->slot); 1027 1.5 mrg ctx->slot_queue.PushBack(thr->slot); 1028 1.5 mrg } 1029 1.5 mrg if (recycle) 1030 1.5 mrg ctx->trace_part_recycle.PushBack(recycle); 1031 1.5 mrg } 1032 1.5 mrg DPrintf("#%d: TraceSwitchPart exit parts=%p-%p pos=0x%zx\n", thr->tid, 1033 1.5 mrg trace->parts.Front(), trace->parts.Back(), 1034 1.5 mrg atomic_load_relaxed(&thr->trace_pos)); 1035 1.3 mrg } 1036 1.3 mrg 1037 1.5 mrg void ThreadIgnoreBegin(ThreadState* thr, uptr pc) { 1038 1.1 mrg DPrintf("#%d: ThreadIgnoreBegin\n", thr->tid); 1039 1.1 mrg thr->ignore_reads_and_writes++; 1040 1.1 mrg CHECK_GT(thr->ignore_reads_and_writes, 0); 1041 1.1 mrg thr->fast_state.SetIgnoreBit(); 1042 1.1 mrg #if !SANITIZER_GO 1043 1.3 mrg if (pc && !ctx->after_multithreaded_fork) 1044 1.1 mrg thr->mop_ignore_set.Add(CurrentStackId(thr, pc)); 1045 1.1 mrg #endif 1046 1.1 mrg } 1047 1.1 mrg 1048 1.3 mrg void ThreadIgnoreEnd(ThreadState *thr) { 1049 1.1 mrg DPrintf("#%d: ThreadIgnoreEnd\n", thr->tid); 1050 1.1 mrg CHECK_GT(thr->ignore_reads_and_writes, 0); 1051 1.1 mrg thr->ignore_reads_and_writes--; 1052 1.1 mrg if (thr->ignore_reads_and_writes == 0) { 1053 1.1 mrg thr->fast_state.ClearIgnoreBit(); 1054 1.1 mrg #if !SANITIZER_GO 1055 1.1 mrg thr->mop_ignore_set.Reset(); 1056 1.1 mrg #endif 1057 1.1 mrg } 1058 1.1 mrg } 1059 1.1 mrg 1060 1.1 mrg #if !SANITIZER_GO 1061 1.1 mrg extern "C" SANITIZER_INTERFACE_ATTRIBUTE 1062 1.1 mrg uptr __tsan_testonly_shadow_stack_current_size() { 1063 1.1 mrg ThreadState *thr = cur_thread(); 1064 1.1 mrg return thr->shadow_stack_pos - thr->shadow_stack; 1065 1.1 mrg } 1066 1.1 mrg #endif 1067 1.1 mrg 1068 1.3 mrg void ThreadIgnoreSyncBegin(ThreadState *thr, uptr pc) { 1069 1.1 mrg DPrintf("#%d: ThreadIgnoreSyncBegin\n", thr->tid); 1070 1.1 mrg thr->ignore_sync++; 1071 1.1 mrg CHECK_GT(thr->ignore_sync, 0); 1072 1.1 mrg #if !SANITIZER_GO 1073 1.3 mrg if (pc && !ctx->after_multithreaded_fork) 1074 1.1 mrg thr->sync_ignore_set.Add(CurrentStackId(thr, pc)); 1075 1.1 mrg #endif 1076 1.1 mrg } 1077 1.1 mrg 1078 1.3 mrg void ThreadIgnoreSyncEnd(ThreadState *thr) { 1079 1.1 mrg DPrintf("#%d: ThreadIgnoreSyncEnd\n", thr->tid); 1080 1.1 mrg CHECK_GT(thr->ignore_sync, 0); 1081 1.1 mrg thr->ignore_sync--; 1082 1.1 mrg #if !SANITIZER_GO 1083 1.1 mrg if (thr->ignore_sync == 0) 1084 1.1 mrg thr->sync_ignore_set.Reset(); 1085 1.1 mrg #endif 1086 1.1 mrg } 1087 1.1 mrg 1088 1.1 mrg bool MD5Hash::operator==(const MD5Hash &other) const { 1089 1.1 mrg return hash[0] == other.hash[0] && hash[1] == other.hash[1]; 1090 1.1 mrg } 1091 1.1 mrg 1092 1.1 mrg #if SANITIZER_DEBUG 1093 1.1 mrg void build_consistency_debug() {} 1094 1.1 mrg #else 1095 1.1 mrg void build_consistency_release() {} 1096 1.1 mrg #endif 1097 1.3 mrg } // namespace __tsan 1098 1.1 mrg 1099 1.3 mrg #if SANITIZER_CHECK_DEADLOCKS 1100 1.3 mrg namespace __sanitizer { 1101 1.3 mrg using namespace __tsan; 1102 1.3 mrg MutexMeta mutex_meta[] = { 1103 1.3 mrg {MutexInvalid, "Invalid", {}}, 1104 1.5 mrg {MutexThreadRegistry, 1105 1.5 mrg "ThreadRegistry", 1106 1.5 mrg {MutexTypeSlots, MutexTypeTrace, MutexTypeReport}}, 1107 1.5 mrg {MutexTypeReport, "Report", {MutexTypeTrace}}, 1108 1.5 mrg {MutexTypeSyncVar, "SyncVar", {MutexTypeReport, MutexTypeTrace}}, 1109 1.3 mrg {MutexTypeAnnotations, "Annotations", {}}, 1110 1.5 mrg {MutexTypeAtExit, "AtExit", {}}, 1111 1.3 mrg {MutexTypeFired, "Fired", {MutexLeaf}}, 1112 1.3 mrg {MutexTypeRacy, "Racy", {MutexLeaf}}, 1113 1.5 mrg {MutexTypeGlobalProc, "GlobalProc", {MutexTypeSlot, MutexTypeSlots}}, 1114 1.5 mrg {MutexTypeInternalAlloc, "InternalAlloc", {MutexLeaf}}, 1115 1.5 mrg {MutexTypeTrace, "Trace", {}}, 1116 1.5 mrg {MutexTypeSlot, 1117 1.5 mrg "Slot", 1118 1.5 mrg {MutexMulti, MutexTypeTrace, MutexTypeSyncVar, MutexThreadRegistry, 1119 1.5 mrg MutexTypeSlots}}, 1120 1.5 mrg {MutexTypeSlots, "Slots", {MutexTypeTrace, MutexTypeReport}}, 1121 1.3 mrg {}, 1122 1.3 mrg }; 1123 1.1 mrg 1124 1.3 mrg void PrintMutexPC(uptr pc) { StackTrace(&pc, 1).Print(); } 1125 1.5 mrg 1126 1.3 mrg } // namespace __sanitizer 1127 1.1 mrg #endif 1128