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 volatile int __tsan_resumed = 0;
32 
__tsan_resume()33 extern "C" void __tsan_resume() {
34   __tsan_resumed = 1;
35 }
36 
37 SANITIZER_WEAK_DEFAULT_IMPL
__tsan_test_only_on_fork()38 void __tsan_test_only_on_fork() {}
39 
40 namespace __tsan {
41 
42 #if !SANITIZER_GO
43 void (*on_initialize)(void);
44 int (*on_finalize)(int);
45 #endif
46 
47 #if !SANITIZER_GO && !SANITIZER_APPLE
48 __attribute__((tls_model("initial-exec")))
49 THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED(
50     SANITIZER_CACHE_LINE_SIZE);
51 #endif
52 static char ctx_placeholder[sizeof(Context)] ALIGNED(SANITIZER_CACHE_LINE_SIZE);
53 Context *ctx;
54 
55 // Can be overriden by a front-end.
56 #ifdef TSAN_EXTERNAL_HOOKS
57 bool OnFinalize(bool failed);
58 void OnInitialize();
59 #else
60 #include <dlfcn.h>
61 SANITIZER_WEAK_CXX_DEFAULT_IMPL
OnFinalize(bool failed)62 bool OnFinalize(bool failed) {
63 #if !SANITIZER_GO
64   if (on_finalize)
65     return on_finalize(failed);
66 #endif
67   return failed;
68 }
69 SANITIZER_WEAK_CXX_DEFAULT_IMPL
OnInitialize()70 void OnInitialize() {
71 #if !SANITIZER_GO
72   if (on_initialize)
73     on_initialize();
74 #endif
75 }
76 #endif
77 
CreateThreadContext(Tid tid)78 static ThreadContextBase *CreateThreadContext(Tid tid) {
79   // Map thread trace when context is created.
80   char name[50];
81   internal_snprintf(name, sizeof(name), "trace %u", tid);
82   MapThreadTrace(GetThreadTrace(tid), TraceSize() * sizeof(Event), name);
83   const uptr hdr = GetThreadTraceHeader(tid);
84   internal_snprintf(name, sizeof(name), "trace header %u", tid);
85   MapThreadTrace(hdr, sizeof(Trace), name);
86   new((void*)hdr) Trace();
87   // We are going to use only a small part of the trace with the default
88   // value of history_size. However, the constructor writes to the whole trace.
89   // Release the unused part.
90   uptr hdr_end = hdr + sizeof(Trace);
91   hdr_end -= sizeof(TraceHeader) * (kTraceParts - TraceParts());
92   hdr_end = RoundUp(hdr_end, GetPageSizeCached());
93   if (hdr_end < hdr + sizeof(Trace)) {
94     ReleaseMemoryPagesToOS(hdr_end, hdr + sizeof(Trace));
95     uptr unused = hdr + sizeof(Trace) - hdr_end;
96     if (hdr_end != (uptr)MmapFixedNoAccess(hdr_end, unused)) {
97       Report("ThreadSanitizer: failed to mprotect [0x%zx-0x%zx) \n", hdr_end,
98              unused);
99       CHECK("unable to mprotect" && 0);
100     }
101   }
102   return New<ThreadContext>(tid);
103 }
104 
105 #if !SANITIZER_GO
106 static const u32 kThreadQuarantineSize = 16;
107 #else
108 static const u32 kThreadQuarantineSize = 64;
109 #endif
110 
Context()111 Context::Context()
112     : initialized(),
113       report_mtx(MutexTypeReport),
114       nreported(),
115       thread_registry(CreateThreadContext, kMaxTid, kThreadQuarantineSize,
116                       kMaxTidReuse),
117       racy_mtx(MutexTypeRacy),
118       racy_stacks(),
119       racy_addresses(),
120       fired_suppressions_mtx(MutexTypeFired),
121       clock_alloc(LINKER_INITIALIZED, "clock allocator") {
122   fired_suppressions.reserve(8);
123 }
124 
125 // The objects are allocated in TLS, so one may rely on zero-initialization.
ThreadState(Context * ctx,Tid tid,int unique_id,u64 epoch,unsigned reuse_count,uptr stk_addr,uptr stk_size,uptr tls_addr,uptr tls_size)126 ThreadState::ThreadState(Context *ctx, Tid tid, int unique_id, u64 epoch,
127                          unsigned reuse_count, uptr stk_addr, uptr stk_size,
128                          uptr tls_addr, uptr tls_size)
129     : fast_state(tid, epoch)
130       // Do not touch these, rely on zero initialization,
131       // they may be accessed before the ctor.
132       // , ignore_reads_and_writes()
133       // , ignore_interceptors()
134       ,
135       clock(tid, reuse_count)
136 #if !SANITIZER_GO
137       ,
138       jmp_bufs()
139 #endif
140       ,
141       tid(tid),
142       unique_id(unique_id),
143       stk_addr(stk_addr),
144       stk_size(stk_size),
145       tls_addr(tls_addr),
146       tls_size(tls_size)
147 #if !SANITIZER_GO
148       ,
149       last_sleep_clock(tid)
150 #endif
151 {
152   CHECK_EQ(reinterpret_cast<uptr>(this) % SANITIZER_CACHE_LINE_SIZE, 0);
153 #if !SANITIZER_GO
154   // C/C++ uses fixed size shadow stack.
155   const int kInitStackSize = kShadowStackSize;
156   shadow_stack = static_cast<uptr *>(
157       MmapNoReserveOrDie(kInitStackSize * sizeof(uptr), "shadow stack"));
158   SetShadowRegionHugePageMode(reinterpret_cast<uptr>(shadow_stack),
159                               kInitStackSize * sizeof(uptr));
160 #else
161   // Go uses malloc-allocated shadow stack with dynamic size.
162   const int kInitStackSize = 8;
163   shadow_stack = static_cast<uptr *>(Alloc(kInitStackSize * sizeof(uptr)));
164 #endif
165   shadow_stack_pos = shadow_stack;
166   shadow_stack_end = shadow_stack + kInitStackSize;
167 }
168 
169 #if !SANITIZER_GO
MemoryProfiler(u64 uptime)170 void MemoryProfiler(u64 uptime) {
171   if (ctx->memprof_fd == kInvalidFd)
172     return;
173   InternalMmapVector<char> buf(4096);
174   WriteMemoryProfile(buf.data(), buf.size(), uptime);
175   WriteToFile(ctx->memprof_fd, buf.data(), internal_strlen(buf.data()));
176 }
177 
InitializeMemoryProfiler()178 void InitializeMemoryProfiler() {
179   ctx->memprof_fd = kInvalidFd;
180   const char *fname = flags()->profile_memory;
181   if (!fname || !fname[0])
182     return;
183   if (internal_strcmp(fname, "stdout") == 0) {
184     ctx->memprof_fd = 1;
185   } else if (internal_strcmp(fname, "stderr") == 0) {
186     ctx->memprof_fd = 2;
187   } else {
188     InternalScopedString filename;
189     filename.append("%s.%d", fname, (int)internal_getpid());
190     ctx->memprof_fd = OpenFile(filename.data(), WrOnly);
191     if (ctx->memprof_fd == kInvalidFd) {
192       Printf("ThreadSanitizer: failed to open memory profile file '%s'\n",
193              filename.data());
194       return;
195     }
196   }
197   MemoryProfiler(0);
198   MaybeSpawnBackgroundThread();
199 }
200 
BackgroundThread(void * arg)201 static void *BackgroundThread(void *arg) {
202   // This is a non-initialized non-user thread, nothing to see here.
203   // We don't use ScopedIgnoreInterceptors, because we want ignores to be
204   // enabled even when the thread function exits (e.g. during pthread thread
205   // shutdown code).
206   cur_thread_init()->ignore_interceptors++;
207   const u64 kMs2Ns = 1000 * 1000;
208   const u64 start = NanoTime();
209 
210   u64 last_flush = NanoTime();
211   uptr last_rss = 0;
212   for (int i = 0;
213       atomic_load(&ctx->stop_background_thread, memory_order_relaxed) == 0;
214       i++) {
215     SleepForMillis(100);
216     u64 now = NanoTime();
217 
218     // Flush memory if requested.
219     if (flags()->flush_memory_ms > 0) {
220       if (last_flush + flags()->flush_memory_ms * kMs2Ns < now) {
221         VPrintf(1, "ThreadSanitizer: periodic memory flush\n");
222         FlushShadowMemory();
223         last_flush = NanoTime();
224       }
225     }
226     if (flags()->memory_limit_mb > 0) {
227       uptr rss = GetRSS();
228       uptr limit = uptr(flags()->memory_limit_mb) << 20;
229       VPrintf(1, "ThreadSanitizer: memory flush check"
230                  " RSS=%llu LAST=%llu LIMIT=%llu\n",
231               (u64)rss >> 20, (u64)last_rss >> 20, (u64)limit >> 20);
232       if (2 * rss > limit + last_rss) {
233         VPrintf(1, "ThreadSanitizer: flushing memory due to RSS\n");
234         FlushShadowMemory();
235         rss = GetRSS();
236         VPrintf(1, "ThreadSanitizer: memory flushed RSS=%llu\n", (u64)rss>>20);
237       }
238       last_rss = rss;
239     }
240 
241     MemoryProfiler(now - start);
242 
243     // Flush symbolizer cache if requested.
244     if (flags()->flush_symbolizer_ms > 0) {
245       u64 last = atomic_load(&ctx->last_symbolize_time_ns,
246                              memory_order_relaxed);
247       if (last != 0 && last + flags()->flush_symbolizer_ms * kMs2Ns < now) {
248         Lock l(&ctx->report_mtx);
249         ScopedErrorReportLock l2;
250         SymbolizeFlush();
251         atomic_store(&ctx->last_symbolize_time_ns, 0, memory_order_relaxed);
252       }
253     }
254   }
255   return nullptr;
256 }
257 
StartBackgroundThread()258 static void StartBackgroundThread() {
259   ctx->background_thread = internal_start_thread(&BackgroundThread, 0);
260 }
261 
262 #ifndef __mips__
StopBackgroundThread()263 static void StopBackgroundThread() {
264   atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed);
265   internal_join_thread(ctx->background_thread);
266   ctx->background_thread = 0;
267 }
268 #endif
269 #endif
270 
DontNeedShadowFor(uptr addr,uptr size)271 void DontNeedShadowFor(uptr addr, uptr size) {
272   ReleaseMemoryPagesToOS(reinterpret_cast<uptr>(MemToShadow(addr)),
273                          reinterpret_cast<uptr>(MemToShadow(addr + size)));
274 }
275 
276 #if !SANITIZER_GO
277 // We call UnmapShadow before the actual munmap, at that point we don't yet
278 // know if the provided address/size are sane. We can't call UnmapShadow
279 // after the actual munmap becuase at that point the memory range can
280 // already be reused for something else, so we can't rely on the munmap
281 // return value to understand is the values are sane.
282 // While calling munmap with insane values (non-canonical address, negative
283 // size, etc) is an error, the kernel won't crash. We must also try to not
284 // crash as the failure mode is very confusing (paging fault inside of the
285 // runtime on some derived shadow address).
IsValidMmapRange(uptr addr,uptr size)286 static bool IsValidMmapRange(uptr addr, uptr size) {
287   if (size == 0)
288     return true;
289   if (static_cast<sptr>(size) < 0)
290     return false;
291   if (!IsAppMem(addr) || !IsAppMem(addr + size - 1))
292     return false;
293   // Check that if the start of the region belongs to one of app ranges,
294   // end of the region belongs to the same region.
295   const uptr ranges[][2] = {
296       {LoAppMemBeg(), LoAppMemEnd()},
297       {MidAppMemBeg(), MidAppMemEnd()},
298       {HiAppMemBeg(), HiAppMemEnd()},
299   };
300   for (auto range : ranges) {
301     if (addr >= range[0] && addr < range[1])
302       return addr + size <= range[1];
303   }
304   return false;
305 }
306 
UnmapShadow(ThreadState * thr,uptr addr,uptr size)307 void UnmapShadow(ThreadState *thr, uptr addr, uptr size) {
308   if (size == 0 || !IsValidMmapRange(addr, size))
309     return;
310   DontNeedShadowFor(addr, size);
311   ScopedGlobalProcessor sgp;
312   ctx->metamap.ResetRange(thr->proc(), addr, size);
313 }
314 #endif
315 
MapShadow(uptr addr,uptr size)316 void MapShadow(uptr addr, uptr size) {
317   // Global data is not 64K aligned, but there are no adjacent mappings,
318   // so we can get away with unaligned mapping.
319   // CHECK_EQ(addr, addr & ~((64 << 10) - 1));  // windows wants 64K alignment
320   const uptr kPageSize = GetPageSizeCached();
321   uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), kPageSize);
322   uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), kPageSize);
323   if (!MmapFixedSuperNoReserve(shadow_begin, shadow_end - shadow_begin,
324                                "shadow"))
325     Die();
326 
327   // Meta shadow is 2:1, so tread carefully.
328   static bool data_mapped = false;
329   static uptr mapped_meta_end = 0;
330   uptr meta_begin = (uptr)MemToMeta(addr);
331   uptr meta_end = (uptr)MemToMeta(addr + size);
332   meta_begin = RoundDownTo(meta_begin, 64 << 10);
333   meta_end = RoundUpTo(meta_end, 64 << 10);
334   if (!data_mapped) {
335     // First call maps data+bss.
336     data_mapped = true;
337     if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin,
338                                  "meta shadow"))
339       Die();
340   } else {
341     // Mapping continuous heap.
342     // Windows wants 64K alignment.
343     meta_begin = RoundDownTo(meta_begin, 64 << 10);
344     meta_end = RoundUpTo(meta_end, 64 << 10);
345     if (meta_end <= mapped_meta_end)
346       return;
347     if (meta_begin < mapped_meta_end)
348       meta_begin = mapped_meta_end;
349     if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin,
350                                  "meta shadow"))
351       Die();
352     mapped_meta_end = meta_end;
353   }
354   VPrintf(2, "mapped meta shadow for (0x%zx-0x%zx) at (0x%zx-0x%zx)\n", addr,
355           addr + size, meta_begin, meta_end);
356 }
357 
MapThreadTrace(uptr addr,uptr size,const char * name)358 void MapThreadTrace(uptr addr, uptr size, const char *name) {
359   DPrintf("#0: Mapping trace at 0x%zx-0x%zx(0x%zx)\n", addr, addr + size, size);
360   CHECK_GE(addr, TraceMemBeg());
361   CHECK_LE(addr + size, TraceMemEnd());
362   CHECK_EQ(addr, addr & ~((64 << 10) - 1));  // windows wants 64K alignment
363   if (!MmapFixedSuperNoReserve(addr, size, name)) {
364     Printf("FATAL: ThreadSanitizer can not mmap thread trace (0x%zx/0x%zx)\n",
365            addr, size);
366     Die();
367   }
368 }
369 
370 #if !SANITIZER_GO
OnStackUnwind(const SignalContext & sig,const void *,BufferedStackTrace * stack)371 static void OnStackUnwind(const SignalContext &sig, const void *,
372                           BufferedStackTrace *stack) {
373   stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,
374                 common_flags()->fast_unwind_on_fatal);
375 }
376 
TsanOnDeadlySignal(int signo,void * siginfo,void * context)377 static void TsanOnDeadlySignal(int signo, void *siginfo, void *context) {
378   HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr);
379 }
380 #endif
381 
CheckUnwind()382 void CheckUnwind() {
383   // There is high probability that interceptors will check-fail as well,
384   // on the other hand there is no sense in processing interceptors
385   // since we are going to die soon.
386   ScopedIgnoreInterceptors ignore;
387 #if !SANITIZER_GO
388   cur_thread()->ignore_sync++;
389   cur_thread()->ignore_reads_and_writes++;
390 #endif
391   PrintCurrentStackSlow(StackTrace::GetCurrentPc());
392 }
393 
394 bool is_initialized;
395 
Initialize(ThreadState * thr)396 void Initialize(ThreadState *thr) {
397   // Thread safe because done before all threads exist.
398   if (is_initialized)
399     return;
400   is_initialized = true;
401   // We are not ready to handle interceptors yet.
402   ScopedIgnoreInterceptors ignore;
403   SanitizerToolName = "ThreadSanitizer";
404   // Install tool-specific callbacks in sanitizer_common.
405   SetCheckUnwindCallback(CheckUnwind);
406 
407   ctx = new(ctx_placeholder) Context;
408   const char *env_name = SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS";
409   const char *options = GetEnv(env_name);
410   CacheBinaryName();
411   CheckASLR();
412   InitializeFlags(&ctx->flags, options, env_name);
413   AvoidCVE_2016_2143();
414   __sanitizer::InitializePlatformEarly();
415   __tsan::InitializePlatformEarly();
416 
417 #if !SANITIZER_GO
418   // Re-exec ourselves if we need to set additional env or command line args.
419   MaybeReexec();
420 
421   InitializeAllocator();
422   ReplaceSystemMalloc();
423 #endif
424   if (common_flags()->detect_deadlocks)
425     ctx->dd = DDetector::Create(flags());
426   Processor *proc = ProcCreate();
427   ProcWire(proc, thr);
428   InitializeInterceptors();
429   InitializePlatform();
430   InitializeDynamicAnnotations();
431 #if !SANITIZER_GO
432   InitializeShadowMemory();
433   InitializeAllocatorLate();
434   InstallDeadlySignalHandlers(TsanOnDeadlySignal);
435 #endif
436   // Setup correct file descriptor for error reports.
437   __sanitizer_set_report_path(common_flags()->log_path);
438   InitializeSuppressions();
439 #if !SANITIZER_GO
440   InitializeLibIgnore();
441   Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer);
442 #endif
443 
444   VPrintf(1, "***** Running under ThreadSanitizer v2 (pid %d) *****\n",
445           (int)internal_getpid());
446 
447   // Initialize thread 0.
448   Tid tid = ThreadCreate(thr, 0, 0, true);
449   CHECK_EQ(tid, kMainTid);
450   ThreadStart(thr, tid, GetTid(), ThreadType::Regular);
451 #if TSAN_CONTAINS_UBSAN
452   __ubsan::InitAsPlugin();
453 #endif
454   ctx->initialized = true;
455 
456 #if !SANITIZER_GO
457   Symbolizer::LateInitialize();
458   InitializeMemoryProfiler();
459 #endif
460 
461   if (flags()->stop_on_start) {
462     Printf("ThreadSanitizer is suspended at startup (pid %d)."
463            " Call __tsan_resume().\n",
464            (int)internal_getpid());
465     while (__tsan_resumed == 0) {}
466   }
467 
468   OnInitialize();
469 }
470 
MaybeSpawnBackgroundThread()471 void MaybeSpawnBackgroundThread() {
472   // On MIPS, TSan initialization is run before
473   // __pthread_initialize_minimal_internal() is finished, so we can not spawn
474   // new threads.
475 #if !SANITIZER_GO && !defined(__mips__)
476   static atomic_uint32_t bg_thread = {};
477   if (atomic_load(&bg_thread, memory_order_relaxed) == 0 &&
478       atomic_exchange(&bg_thread, 1, memory_order_relaxed) == 0) {
479     StartBackgroundThread();
480     SetSandboxingCallback(StopBackgroundThread);
481   }
482 #endif
483 }
484 
485 
Finalize(ThreadState * thr)486 int Finalize(ThreadState *thr) {
487   bool failed = false;
488 
489   if (common_flags()->print_module_map == 1)
490     DumpProcessMap();
491 
492   if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1)
493     SleepForMillis(flags()->atexit_sleep_ms);
494 
495   // Wait for pending reports.
496   ctx->report_mtx.Lock();
497   { ScopedErrorReportLock l; }
498   ctx->report_mtx.Unlock();
499 
500 #if !SANITIZER_GO
501   if (Verbosity()) AllocatorPrintStats();
502 #endif
503 
504   ThreadFinalize(thr);
505 
506   if (ctx->nreported) {
507     failed = true;
508 #if !SANITIZER_GO
509     Printf("ThreadSanitizer: reported %d warnings\n", ctx->nreported);
510 #else
511     Printf("Found %d data race(s)\n", ctx->nreported);
512 #endif
513   }
514 
515   if (common_flags()->print_suppressions)
516     PrintMatchedSuppressions();
517 
518   failed = OnFinalize(failed);
519 
520   return failed ? common_flags()->exitcode : 0;
521 }
522 
523 #if !SANITIZER_GO
ForkBefore(ThreadState * thr,uptr pc)524 void ForkBefore(ThreadState *thr, uptr pc) SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
525   ctx->thread_registry.Lock();
526   ctx->report_mtx.Lock();
527   ScopedErrorReportLock::Lock();
528   AllocatorLock();
529   // Suppress all reports in the pthread_atfork callbacks.
530   // Reports will deadlock on the report_mtx.
531   // We could ignore sync operations as well,
532   // but so far it's unclear if it will do more good or harm.
533   // Unnecessarily ignoring things can lead to false positives later.
534   thr->suppress_reports++;
535   // On OS X, REAL(fork) can call intercepted functions (OSSpinLockLock), and
536   // we'll assert in CheckNoLocks() unless we ignore interceptors.
537   // On OS X libSystem_atfork_prepare/parent/child callbacks are called
538   // after/before our callbacks and they call free.
539   thr->ignore_interceptors++;
540   // Disables memory write in OnUserAlloc/Free.
541   thr->ignore_reads_and_writes++;
542 
543   __tsan_test_only_on_fork();
544 }
545 
ForkParentAfter(ThreadState * thr,uptr pc)546 void ForkParentAfter(ThreadState *thr,
547                      uptr pc) SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
548   thr->suppress_reports--;  // Enabled in ForkBefore.
549   thr->ignore_interceptors--;
550   thr->ignore_reads_and_writes--;
551   AllocatorUnlock();
552   ScopedErrorReportLock::Unlock();
553   ctx->report_mtx.Unlock();
554   ctx->thread_registry.Unlock();
555 }
556 
ForkChildAfter(ThreadState * thr,uptr pc,bool start_thread)557 void ForkChildAfter(ThreadState *thr, uptr pc,
558                     bool start_thread) SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
559   thr->suppress_reports--;  // Enabled in ForkBefore.
560   thr->ignore_interceptors--;
561   thr->ignore_reads_and_writes--;
562   AllocatorUnlock();
563   ScopedErrorReportLock::Unlock();
564   ctx->report_mtx.Unlock();
565   ctx->thread_registry.Unlock();
566 
567   uptr nthread = 0;
568   ctx->thread_registry.GetNumberOfThreads(0, 0, &nthread /* alive threads */);
569   VPrintf(1, "ThreadSanitizer: forked new process with pid %d,"
570       " parent had %d threads\n", (int)internal_getpid(), (int)nthread);
571   if (nthread == 1) {
572     if (start_thread)
573       StartBackgroundThread();
574   } else {
575     // We've just forked a multi-threaded process. We cannot reasonably function
576     // after that (some mutexes may be locked before fork). So just enable
577     // ignores for everything in the hope that we will exec soon.
578     ctx->after_multithreaded_fork = true;
579     thr->ignore_interceptors++;
580     ThreadIgnoreBegin(thr, pc);
581     ThreadIgnoreSyncBegin(thr, pc);
582   }
583 }
584 #endif
585 
586 #if SANITIZER_GO
587 NOINLINE
GrowShadowStack(ThreadState * thr)588 void GrowShadowStack(ThreadState *thr) {
589   const int sz = thr->shadow_stack_end - thr->shadow_stack;
590   const int newsz = 2 * sz;
591   auto *newstack = (uptr *)Alloc(newsz * sizeof(uptr));
592   internal_memcpy(newstack, thr->shadow_stack, sz * sizeof(uptr));
593   Free(thr->shadow_stack);
594   thr->shadow_stack = newstack;
595   thr->shadow_stack_pos = newstack + sz;
596   thr->shadow_stack_end = newstack + newsz;
597 }
598 #endif
599 
CurrentStackId(ThreadState * thr,uptr pc)600 StackID CurrentStackId(ThreadState *thr, uptr pc) {
601   if (!thr->is_inited)  // May happen during bootstrap.
602     return kInvalidStackID;
603   if (pc != 0) {
604 #if !SANITIZER_GO
605     DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end);
606 #else
607     if (thr->shadow_stack_pos == thr->shadow_stack_end)
608       GrowShadowStack(thr);
609 #endif
610     thr->shadow_stack_pos[0] = pc;
611     thr->shadow_stack_pos++;
612   }
613   StackID id = StackDepotPut(
614       StackTrace(thr->shadow_stack, thr->shadow_stack_pos - thr->shadow_stack));
615   if (pc != 0)
616     thr->shadow_stack_pos--;
617   return id;
618 }
619 
620 namespace v3 {
621 
622 NOINLINE
TraceSwitchPart(ThreadState * thr)623 void TraceSwitchPart(ThreadState *thr) {
624   Trace *trace = &thr->tctx->trace;
625   Event *pos = reinterpret_cast<Event *>(atomic_load_relaxed(&thr->trace_pos));
626   DCHECK_EQ(reinterpret_cast<uptr>(pos + 1) & TracePart::kAlignment, 0);
627   auto *part = trace->parts.Back();
628   DPrintf("TraceSwitchPart part=%p pos=%p\n", part, pos);
629   if (part) {
630     // We can get here when we still have space in the current trace part.
631     // The fast-path check in TraceAcquire has false positives in the middle of
632     // the part. Check if we are indeed at the end of the current part or not,
633     // and fill any gaps with NopEvent's.
634     Event *end = &part->events[TracePart::kSize];
635     DCHECK_GE(pos, &part->events[0]);
636     DCHECK_LE(pos, end);
637     if (pos + 1 < end) {
638       if ((reinterpret_cast<uptr>(pos) & TracePart::kAlignment) ==
639           TracePart::kAlignment)
640         *pos++ = NopEvent;
641       *pos++ = NopEvent;
642       DCHECK_LE(pos + 2, end);
643       atomic_store_relaxed(&thr->trace_pos, reinterpret_cast<uptr>(pos));
644       // Ensure we setup trace so that the next TraceAcquire
645       // won't detect trace part end.
646       Event *ev;
647       CHECK(TraceAcquire(thr, &ev));
648       return;
649     }
650     // We are indeed at the end.
651     for (; pos < end; pos++) *pos = NopEvent;
652   }
653 #if !SANITIZER_GO
654   if (ctx->after_multithreaded_fork) {
655     // We just need to survive till exec.
656     CHECK(part);
657     atomic_store_relaxed(&thr->trace_pos,
658                          reinterpret_cast<uptr>(&part->events[0]));
659     return;
660   }
661 #endif
662   part = new (MmapOrDie(sizeof(TracePart), "TracePart")) TracePart();
663   part->trace = trace;
664   thr->trace_prev_pc = 0;
665   {
666     Lock lock(&trace->mtx);
667     trace->parts.PushBack(part);
668     atomic_store_relaxed(&thr->trace_pos,
669                          reinterpret_cast<uptr>(&part->events[0]));
670   }
671   // Make this part self-sufficient by restoring the current stack
672   // and mutex set in the beginning of the trace.
673   TraceTime(thr);
674   for (uptr *pos = &thr->shadow_stack[0]; pos < thr->shadow_stack_pos; pos++)
675     CHECK(TryTraceFunc(thr, *pos));
676   for (uptr i = 0; i < thr->mset.Size(); i++) {
677     MutexSet::Desc d = thr->mset.Get(i);
678     TraceMutexLock(thr, d.write ? EventType::kLock : EventType::kRLock, 0,
679                    d.addr, d.stack_id);
680   }
681 }
682 
683 }  // namespace v3
684 
TraceSwitch(ThreadState * thr)685 void TraceSwitch(ThreadState *thr) {
686 #if !SANITIZER_GO
687   if (ctx->after_multithreaded_fork)
688     return;
689 #endif
690   thr->nomalloc++;
691   Trace *thr_trace = ThreadTrace(thr->tid);
692   Lock l(&thr_trace->mtx);
693   unsigned trace = (thr->fast_state.epoch() / kTracePartSize) % TraceParts();
694   TraceHeader *hdr = &thr_trace->headers[trace];
695   hdr->epoch0 = thr->fast_state.epoch();
696   ObtainCurrentStack(thr, 0, &hdr->stack0);
697   hdr->mset0 = thr->mset;
698   thr->nomalloc--;
699 }
700 
ThreadTrace(Tid tid)701 Trace *ThreadTrace(Tid tid) { return (Trace *)GetThreadTraceHeader(tid); }
702 
TraceTopPC(ThreadState * thr)703 uptr TraceTopPC(ThreadState *thr) {
704   Event *events = (Event*)GetThreadTrace(thr->tid);
705   uptr pc = events[thr->fast_state.GetTracePos()];
706   return pc;
707 }
708 
TraceSize()709 uptr TraceSize() {
710   return (uptr)(1ull << (kTracePartSizeBits + flags()->history_size + 1));
711 }
712 
TraceParts()713 uptr TraceParts() {
714   return TraceSize() / kTracePartSize;
715 }
716 
717 #if !SANITIZER_GO
__tsan_trace_switch()718 extern "C" void __tsan_trace_switch() {
719   TraceSwitch(cur_thread());
720 }
721 
__tsan_report_race()722 extern "C" void __tsan_report_race() {
723   ReportRace(cur_thread());
724 }
725 #endif
726 
ThreadIgnoreBegin(ThreadState * thr,uptr pc)727 void ThreadIgnoreBegin(ThreadState *thr, uptr pc) {
728   DPrintf("#%d: ThreadIgnoreBegin\n", thr->tid);
729   thr->ignore_reads_and_writes++;
730   CHECK_GT(thr->ignore_reads_and_writes, 0);
731   thr->fast_state.SetIgnoreBit();
732 #if !SANITIZER_GO
733   if (pc && !ctx->after_multithreaded_fork)
734     thr->mop_ignore_set.Add(CurrentStackId(thr, pc));
735 #endif
736 }
737 
ThreadIgnoreEnd(ThreadState * thr)738 void ThreadIgnoreEnd(ThreadState *thr) {
739   DPrintf("#%d: ThreadIgnoreEnd\n", thr->tid);
740   CHECK_GT(thr->ignore_reads_and_writes, 0);
741   thr->ignore_reads_and_writes--;
742   if (thr->ignore_reads_and_writes == 0) {
743     thr->fast_state.ClearIgnoreBit();
744 #if !SANITIZER_GO
745     thr->mop_ignore_set.Reset();
746 #endif
747   }
748 }
749 
750 #if !SANITIZER_GO
751 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
__tsan_testonly_shadow_stack_current_size()752 uptr __tsan_testonly_shadow_stack_current_size() {
753   ThreadState *thr = cur_thread();
754   return thr->shadow_stack_pos - thr->shadow_stack;
755 }
756 #endif
757 
ThreadIgnoreSyncBegin(ThreadState * thr,uptr pc)758 void ThreadIgnoreSyncBegin(ThreadState *thr, uptr pc) {
759   DPrintf("#%d: ThreadIgnoreSyncBegin\n", thr->tid);
760   thr->ignore_sync++;
761   CHECK_GT(thr->ignore_sync, 0);
762 #if !SANITIZER_GO
763   if (pc && !ctx->after_multithreaded_fork)
764     thr->sync_ignore_set.Add(CurrentStackId(thr, pc));
765 #endif
766 }
767 
ThreadIgnoreSyncEnd(ThreadState * thr)768 void ThreadIgnoreSyncEnd(ThreadState *thr) {
769   DPrintf("#%d: ThreadIgnoreSyncEnd\n", thr->tid);
770   CHECK_GT(thr->ignore_sync, 0);
771   thr->ignore_sync--;
772 #if !SANITIZER_GO
773   if (thr->ignore_sync == 0)
774     thr->sync_ignore_set.Reset();
775 #endif
776 }
777 
operator ==(const MD5Hash & other) const778 bool MD5Hash::operator==(const MD5Hash &other) const {
779   return hash[0] == other.hash[0] && hash[1] == other.hash[1];
780 }
781 
782 #if SANITIZER_DEBUG
build_consistency_debug()783 void build_consistency_debug() {}
784 #else
build_consistency_release()785 void build_consistency_release() {}
786 #endif
787 
788 }  // namespace __tsan
789 
790 #if SANITIZER_CHECK_DEADLOCKS
791 namespace __sanitizer {
792 using namespace __tsan;
793 MutexMeta mutex_meta[] = {
794     {MutexInvalid, "Invalid", {}},
795     {MutexThreadRegistry, "ThreadRegistry", {}},
796     {MutexTypeTrace, "Trace", {}},
797     {MutexTypeReport,
798      "Report",
799      {MutexTypeSyncVar, MutexTypeGlobalProc, MutexTypeTrace}},
800     {MutexTypeSyncVar, "SyncVar", {MutexTypeTrace}},
801     {MutexTypeAnnotations, "Annotations", {}},
802     {MutexTypeAtExit, "AtExit", {MutexTypeSyncVar}},
803     {MutexTypeFired, "Fired", {MutexLeaf}},
804     {MutexTypeRacy, "Racy", {MutexLeaf}},
805     {MutexTypeGlobalProc, "GlobalProc", {}},
806     {MutexTypeInternalAlloc, "InternalAlloc", {MutexLeaf}},
807     {},
808 };
809 
PrintMutexPC(uptr pc)810 void PrintMutexPC(uptr pc) { StackTrace(&pc, 1).Print(); }
811 }  // namespace __sanitizer
812 #endif
813