//===-- tsan_rtl.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer (TSan), a race detector.
//
// Main file (entry points) for the TSan run-time.
//===----------------------------------------------------------------------===//

#include "tsan_rtl.h"

#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_file.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_placement_new.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_symbolizer.h"
#include "tsan_defs.h"
#include "tsan_interface.h"
#include "tsan_mman.h"
#include "tsan_platform.h"
#include "tsan_suppressions.h"
#include "tsan_symbolize.h"
#include "ubsan/ubsan_init.h"

volatile int __tsan_resumed = 0;

extern "C" void __tsan_resume() {
  __tsan_resumed = 1;
}

SANITIZER_WEAK_DEFAULT_IMPL
void __tsan_test_only_on_fork() {}

namespace __tsan {

#if !SANITIZER_GO
void (*on_initialize)(void);
int (*on_finalize)(int);
#endif

#if !SANITIZER_GO && !SANITIZER_MAC
__attribute__((tls_model("initial-exec")))
THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED(
    SANITIZER_CACHE_LINE_SIZE);
#endif
static char ctx_placeholder[sizeof(Context)] ALIGNED(SANITIZER_CACHE_LINE_SIZE);
Context *ctx;

// Can be overriden by a front-end.
#ifdef TSAN_EXTERNAL_HOOKS
bool OnFinalize(bool failed);
void OnInitialize();
#else
SANITIZER_WEAK_CXX_DEFAULT_IMPL
bool OnFinalize(bool failed) {
#  if !SANITIZER_GO
  if (on_finalize)
    return on_finalize(failed);
#  endif
  return failed;
}

SANITIZER_WEAK_CXX_DEFAULT_IMPL
void OnInitialize() {
#  if !SANITIZER_GO
  if (on_initialize)
    on_initialize();
#  endif
}
#endif

static TracePart* TracePartAlloc(ThreadState* thr) {
  TracePart* part = nullptr;
  {
    Lock lock(&ctx->slot_mtx);
    uptr max_parts = Trace::kMinParts + flags()->history_size;
    Trace* trace = &thr->tctx->trace;
    if (trace->parts_allocated == max_parts ||
        ctx->trace_part_finished_excess) {
      part = ctx->trace_part_recycle.PopFront();
      DPrintf("#%d: TracePartAlloc: part=%p\n", thr->tid, part);
      if (part && part->trace) {
        Trace* trace1 = part->trace;
        Lock trace_lock(&trace1->mtx);
        part->trace = nullptr;
        TracePart* part1 = trace1->parts.PopFront();
        CHECK_EQ(part, part1);
        if (trace1->parts_allocated > trace1->parts.Size()) {
          ctx->trace_part_finished_excess +=
              trace1->parts_allocated - trace1->parts.Size();
          trace1->parts_allocated = trace1->parts.Size();
        }
      }
    }
    if (trace->parts_allocated < max_parts) {
      trace->parts_allocated++;
      if (ctx->trace_part_finished_excess)
        ctx->trace_part_finished_excess--;
    }
    if (!part)
      ctx->trace_part_total_allocated++;
    else if (ctx->trace_part_recycle_finished)
      ctx->trace_part_recycle_finished--;
  }
  if (!part)
    part = new (MmapOrDie(sizeof(*part), "TracePart")) TracePart();
  return part;
}

static void TracePartFree(TracePart* part) REQUIRES(ctx->slot_mtx) {
  DCHECK(part->trace);
  part->trace = nullptr;
  ctx->trace_part_recycle.PushFront(part);
}

void TraceResetForTesting() {
  Lock lock(&ctx->slot_mtx);
  while (auto* part = ctx->trace_part_recycle.PopFront()) {
    if (auto trace = part->trace)
      CHECK_EQ(trace->parts.PopFront(), part);
    UnmapOrDie(part, sizeof(*part));
  }
  ctx->trace_part_total_allocated = 0;
  ctx->trace_part_recycle_finished = 0;
  ctx->trace_part_finished_excess = 0;
}

static void DoResetImpl(uptr epoch) {
  ThreadRegistryLock lock0(&ctx->thread_registry);
  Lock lock1(&ctx->slot_mtx);
  CHECK_EQ(ctx->global_epoch, epoch);
  ctx->global_epoch++;
  CHECK(!ctx->resetting);
  ctx->resetting = true;
  for (u32 i = ctx->thread_registry.NumThreadsLocked(); i--;) {
    ThreadContext* tctx = (ThreadContext*)ctx->thread_registry.GetThreadLocked(
        static_cast<Tid>(i));
    // Potentially we could purge all ThreadStatusDead threads from the
    // registry. Since we reset all shadow, they can't race with anything
    // anymore. However, their tid's can still be stored in some aux places
    // (e.g. tid of thread that created something).
    auto trace = &tctx->trace;
    Lock lock(&trace->mtx);
    bool attached = tctx->thr && tctx->thr->slot;
    auto parts = &trace->parts;
    bool local = false;
    while (!parts->Empty()) {
      auto part = parts->Front();
      local = local || part == trace->local_head;
      if (local)
        CHECK(!ctx->trace_part_recycle.Queued(part));
      else
        ctx->trace_part_recycle.Remove(part);
      if (attached && parts->Size() == 1) {
        // The thread is running and this is the last/current part.
        // Set the trace position to the end of the current part
        // to force the thread to call SwitchTracePart and re-attach
        // to a new slot and allocate a new trace part.
        // Note: the thread is concurrently modifying the position as well,
        // so this is only best-effort. The thread can only modify position
        // within this part, because switching parts is protected by
        // slot/trace mutexes that we hold here.
        atomic_store_relaxed(
            &tctx->thr->trace_pos,
            reinterpret_cast<uptr>(&part->events[TracePart::kSize]));
        break;
      }
      parts->Remove(part);
      TracePartFree(part);
    }
    CHECK_LE(parts->Size(), 1);
    trace->local_head = parts->Front();
    if (tctx->thr && !tctx->thr->slot) {
      atomic_store_relaxed(&tctx->thr->trace_pos, 0);
      tctx->thr->trace_prev_pc = 0;
    }
    if (trace->parts_allocated > trace->parts.Size()) {
      ctx->trace_part_finished_excess +=
          trace->parts_allocated - trace->parts.Size();
      trace->parts_allocated = trace->parts.Size();
    }
  }
  while (ctx->slot_queue.PopFront()) {
  }
  for (auto& slot : ctx->slots) {
    slot.SetEpoch(kEpochZero);
    slot.journal.Reset();
    slot.thr = nullptr;
    ctx->slot_queue.PushBack(&slot);
  }

  DPrintf("Resetting shadow...\n");
  if (!MmapFixedSuperNoReserve(ShadowBeg(), ShadowEnd() - ShadowBeg(),
                               "shadow")) {
    Printf("failed to reset shadow memory\n");
    Die();
  }
  DPrintf("Resetting meta shadow...\n");
  ctx->metamap.ResetClocks();
  ctx->resetting = false;
}

// Clang does not understand locking all slots in the loop:
// error: expecting mutex 'slot.mtx' to be held at start of each loop
void DoReset(ThreadState* thr, uptr epoch) NO_THREAD_SAFETY_ANALYSIS {
  {
    Lock l(&ctx->multi_slot_mtx);
    for (auto& slot : ctx->slots) {
      slot.mtx.Lock();
      if (UNLIKELY(epoch == 0))
        epoch = ctx->global_epoch;
      if (UNLIKELY(epoch != ctx->global_epoch)) {
        // Epoch can't change once we've locked the first slot.
        CHECK_EQ(slot.sid, 0);
        slot.mtx.Unlock();
        return;
      }
    }
  }
  DPrintf("#%d: DoReset epoch=%lu\n", thr ? thr->tid : -1, epoch);
  DoResetImpl(epoch);
  for (auto& slot : ctx->slots) slot.mtx.Unlock();
}

void FlushShadowMemory() { DoReset(nullptr, 0); }

static TidSlot* FindSlotAndLock(ThreadState* thr)
    ACQUIRE(thr->slot->mtx) NO_THREAD_SAFETY_ANALYSIS {
  CHECK(!thr->slot);
  TidSlot* slot = nullptr;
  for (;;) {
    uptr epoch;
    {
      Lock lock(&ctx->slot_mtx);
      epoch = ctx->global_epoch;
      if (slot) {
        // This is an exhausted slot from the previous iteration.
        if (ctx->slot_queue.Queued(slot))
          ctx->slot_queue.Remove(slot);
        thr->slot_locked = false;
        slot->mtx.Unlock();
      }
      for (;;) {
        slot = ctx->slot_queue.PopFront();
        if (!slot)
          break;
        if (slot->epoch() != kEpochLast) {
          ctx->slot_queue.PushBack(slot);
          break;
        }
      }
    }
    if (!slot) {
      DoReset(thr, epoch);
      continue;
    }
    slot->mtx.Lock();
    CHECK(!thr->slot_locked);
    thr->slot_locked = true;
    if (slot->thr) {
      DPrintf("#%d: preempting sid=%d tid=%d\n", thr->tid, (u32)slot->sid,
              slot->thr->tid);
      slot->SetEpoch(slot->thr->fast_state.epoch());
      slot->thr = nullptr;
    }
    if (slot->epoch() != kEpochLast)
      return slot;
  }
}

void SlotAttachAndLock(ThreadState* thr) {
  TidSlot* slot = FindSlotAndLock(thr);
  DPrintf("#%d: SlotAttach: slot=%u\n", thr->tid, static_cast<int>(slot->sid));
  CHECK(!slot->thr);
  CHECK(!thr->slot);
  slot->thr = thr;
  thr->slot = slot;
  Epoch epoch = EpochInc(slot->epoch());
  CHECK(!EpochOverflow(epoch));
  slot->SetEpoch(epoch);
  thr->fast_state.SetSid(slot->sid);
  thr->fast_state.SetEpoch(epoch);
  if (thr->slot_epoch != ctx->global_epoch) {
    thr->slot_epoch = ctx->global_epoch;
    thr->clock.Reset();
#if !SANITIZER_GO
    thr->last_sleep_stack_id = kInvalidStackID;
    thr->last_sleep_clock.Reset();
#endif
  }
  thr->clock.Set(slot->sid, epoch);
  slot->journal.PushBack({thr->tid, epoch});
}

static void SlotDetachImpl(ThreadState* thr, bool exiting) {
  TidSlot* slot = thr->slot;
  thr->slot = nullptr;
  if (thr != slot->thr) {
    slot = nullptr;  // we don't own the slot anymore
    if (thr->slot_epoch != ctx->global_epoch) {
      TracePart* part = nullptr;
      auto* trace = &thr->tctx->trace;
      {
        Lock l(&trace->mtx);
        auto* parts = &trace->parts;
        // The trace can be completely empty in an unlikely event
        // the thread is preempted right after it acquired the slot
        // in ThreadStart and did not trace any events yet.
        CHECK_LE(parts->Size(), 1);
        part = parts->PopFront();
        thr->tctx->trace.local_head = nullptr;
        atomic_store_relaxed(&thr->trace_pos, 0);
        thr->trace_prev_pc = 0;
      }
      if (part) {
        Lock l(&ctx->slot_mtx);
        TracePartFree(part);
      }
    }
    return;
  }
  CHECK(exiting || thr->fast_state.epoch() == kEpochLast);
  slot->SetEpoch(thr->fast_state.epoch());
  slot->thr = nullptr;
}

void SlotDetach(ThreadState* thr) {
  Lock lock(&thr->slot->mtx);
  SlotDetachImpl(thr, true);
}

void SlotLock(ThreadState* thr) NO_THREAD_SAFETY_ANALYSIS {
  DCHECK(!thr->slot_locked);
  TidSlot* slot = thr->slot;
  slot->mtx.Lock();
  thr->slot_locked = true;
  if (LIKELY(thr == slot->thr && thr->fast_state.epoch() != kEpochLast))
    return;
  SlotDetachImpl(thr, false);
  thr->slot_locked = false;
  slot->mtx.Unlock();
  SlotAttachAndLock(thr);
}

void SlotUnlock(ThreadState* thr) {
  DCHECK(thr->slot_locked);
  thr->slot_locked = false;
  thr->slot->mtx.Unlock();
}

Context::Context()
    : initialized(),
      report_mtx(MutexTypeReport),
      nreported(),
      thread_registry([](Tid tid) -> ThreadContextBase* {
        return new (Alloc(sizeof(ThreadContext))) ThreadContext(tid);
      }),
      racy_mtx(MutexTypeRacy),
      racy_stacks(),
      racy_addresses(),
      fired_suppressions_mtx(MutexTypeFired),
      clock_alloc(LINKER_INITIALIZED, "clock allocator"),
      slot_mtx(MutexTypeSlots),
      multi_slot_mtx(MutexTypeMultiSlot),
      resetting() {
  fired_suppressions.reserve(8);
  for (uptr i = 0; i < ARRAY_SIZE(slots); i++) {
    TidSlot* slot = &slots[i];
    slot->sid = static_cast<Sid>(i);
    slot_queue.PushBack(slot);
  }
  global_epoch = 1;
}

TidSlot::TidSlot() : mtx(MutexTypeSlot) {}

// The objects are allocated in TLS, so one may rely on zero-initialization.
ThreadState::ThreadState(Tid tid)
    // Do not touch these, rely on zero initialization,
    // they may be accessed before the ctor.
    // ignore_reads_and_writes()
    // ignore_interceptors()
    : tid(tid) {
  CHECK_EQ(reinterpret_cast<uptr>(this) % SANITIZER_CACHE_LINE_SIZE, 0);
#if !SANITIZER_GO
  // C/C++ uses fixed size shadow stack.
  const int kInitStackSize = kShadowStackSize;
  shadow_stack = static_cast<uptr*>(
      MmapNoReserveOrDie(kInitStackSize * sizeof(uptr), "shadow stack"));
  SetShadowRegionHugePageMode(reinterpret_cast<uptr>(shadow_stack),
                              kInitStackSize * sizeof(uptr));
#else
  // Go uses malloc-allocated shadow stack with dynamic size.
  const int kInitStackSize = 8;
  shadow_stack = static_cast<uptr*>(Alloc(kInitStackSize * sizeof(uptr)));
#endif
  shadow_stack_pos = shadow_stack;
  shadow_stack_end = shadow_stack + kInitStackSize;
}

#if !SANITIZER_GO
void MemoryProfiler(u64 uptime) {
  if (ctx->memprof_fd == kInvalidFd)
    return;
  InternalMmapVector<char> buf(4096);
  WriteMemoryProfile(buf.data(), buf.size(), uptime);
  WriteToFile(ctx->memprof_fd, buf.data(), internal_strlen(buf.data()));
}

void InitializeMemoryProfiler() {
  ctx->memprof_fd = kInvalidFd;
  const char *fname = flags()->profile_memory;
  if (!fname || !fname[0])
    return;
  if (internal_strcmp(fname, "stdout") == 0) {
    ctx->memprof_fd = 1;
  } else if (internal_strcmp(fname, "stderr") == 0) {
    ctx->memprof_fd = 2;
  } else {
    InternalScopedString filename;
    filename.append("%s.%d", fname, (int)internal_getpid());
    ctx->memprof_fd = OpenFile(filename.data(), WrOnly);
    if (ctx->memprof_fd == kInvalidFd) {
      Printf("ThreadSanitizer: failed to open memory profile file '%s'\n",
             filename.data());
      return;
    }
  }
  MemoryProfiler(0);
  MaybeSpawnBackgroundThread();
}

static void *BackgroundThread(void *arg) {
  // This is a non-initialized non-user thread, nothing to see here.
  // We don't use ScopedIgnoreInterceptors, because we want ignores to be
  // enabled even when the thread function exits (e.g. during pthread thread
  // shutdown code).
  cur_thread_init()->ignore_interceptors++;
  const u64 kMs2Ns = 1000 * 1000;
  const u64 start = NanoTime();

  u64 last_flush = NanoTime();
  uptr last_rss = 0;
  for (int i = 0;
      atomic_load(&ctx->stop_background_thread, memory_order_relaxed) == 0;
      i++) {
    SleepForMillis(100);
    u64 now = NanoTime();

    // Flush memory if requested.
    if (flags()->flush_memory_ms > 0) {
      if (last_flush + flags()->flush_memory_ms * kMs2Ns < now) {
        VPrintf(1, "ThreadSanitizer: periodic memory flush\n");
        FlushShadowMemory();
        last_flush = NanoTime();
      }
    }
    if (flags()->memory_limit_mb > 0) {
      uptr rss = GetRSS();
      uptr limit = uptr(flags()->memory_limit_mb) << 20;
      VPrintf(1, "ThreadSanitizer: memory flush check"
                 " RSS=%llu LAST=%llu LIMIT=%llu\n",
              (u64)rss >> 20, (u64)last_rss >> 20, (u64)limit >> 20);
      if (2 * rss > limit + last_rss) {
        VPrintf(1, "ThreadSanitizer: flushing memory due to RSS\n");
        FlushShadowMemory();
        rss = GetRSS();
        VPrintf(1, "ThreadSanitizer: memory flushed RSS=%llu\n", (u64)rss>>20);
      }
      last_rss = rss;
    }

    MemoryProfiler(now - start);

    // Flush symbolizer cache if requested.
    if (flags()->flush_symbolizer_ms > 0) {
      u64 last = atomic_load(&ctx->last_symbolize_time_ns,
                             memory_order_relaxed);
      if (last != 0 && last + flags()->flush_symbolizer_ms * kMs2Ns < now) {
        Lock l(&ctx->report_mtx);
        ScopedErrorReportLock l2;
        SymbolizeFlush();
        atomic_store(&ctx->last_symbolize_time_ns, 0, memory_order_relaxed);
      }
    }
  }
  return nullptr;
}

static void StartBackgroundThread() {
  ctx->background_thread = internal_start_thread(&BackgroundThread, 0);
}

#ifndef __mips__
static void StopBackgroundThread() {
  atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed);
  internal_join_thread(ctx->background_thread);
  ctx->background_thread = 0;
}
#endif
#endif

void DontNeedShadowFor(uptr addr, uptr size) {
  ReleaseMemoryPagesToOS(reinterpret_cast<uptr>(MemToShadow(addr)),
                         reinterpret_cast<uptr>(MemToShadow(addr + size)));
}

#if !SANITIZER_GO
void UnmapShadow(ThreadState *thr, uptr addr, uptr size) {
  if (size == 0) return;
  DontNeedShadowFor(addr, size);
  ScopedGlobalProcessor sgp;
  SlotLocker locker(thr, true);
  ctx->metamap.ResetRange(thr->proc(), addr, size, true);
}
#endif

void MapShadow(uptr addr, uptr size) {
  // Global data is not 64K aligned, but there are no adjacent mappings,
  // so we can get away with unaligned mapping.
  // CHECK_EQ(addr, addr & ~((64 << 10) - 1));  // windows wants 64K alignment
  const uptr kPageSize = GetPageSizeCached();
  uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), kPageSize);
  uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), kPageSize);
  if (!MmapFixedSuperNoReserve(shadow_begin, shadow_end - shadow_begin,
                               "shadow"))
    Die();

  // Meta shadow is 2:1, so tread carefully.
  static bool data_mapped = false;
  static uptr mapped_meta_end = 0;
  uptr meta_begin = (uptr)MemToMeta(addr);
  uptr meta_end = (uptr)MemToMeta(addr + size);
  meta_begin = RoundDownTo(meta_begin, 64 << 10);
  meta_end = RoundUpTo(meta_end, 64 << 10);
  if (!data_mapped) {
    // First call maps data+bss.
    data_mapped = true;
    if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin,
                                 "meta shadow"))
      Die();
  } else {
    // Mapping continuous heap.
    // Windows wants 64K alignment.
    meta_begin = RoundDownTo(meta_begin, 64 << 10);
    meta_end = RoundUpTo(meta_end, 64 << 10);
    if (meta_end <= mapped_meta_end)
      return;
    if (meta_begin < mapped_meta_end)
      meta_begin = mapped_meta_end;
    if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin,
                                 "meta shadow"))
      Die();
    mapped_meta_end = meta_end;
  }
  VPrintf(2, "mapped meta shadow for (0x%zx-0x%zx) at (0x%zx-0x%zx)\n", addr,
          addr + size, meta_begin, meta_end);
}

#if !SANITIZER_GO
static void OnStackUnwind(const SignalContext &sig, const void *,
                          BufferedStackTrace *stack) {
  stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,
                common_flags()->fast_unwind_on_fatal);
}

static void TsanOnDeadlySignal(int signo, void *siginfo, void *context) {
  HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr);
}
#endif

void CheckUnwind() {
  // There is high probability that interceptors will check-fail as well,
  // on the other hand there is no sense in processing interceptors
  // since we are going to die soon.
  ScopedIgnoreInterceptors ignore;
#if !SANITIZER_GO
  ThreadState* thr = cur_thread();
  thr->nomalloc = false;
  thr->ignore_sync++;
  thr->ignore_reads_and_writes++;
  atomic_store_relaxed(&thr->in_signal_handler, 0);
#endif
  PrintCurrentStackSlow(StackTrace::GetCurrentPc());
}

bool is_initialized;

void Initialize(ThreadState *thr) {
  // Thread safe because done before all threads exist.
  if (is_initialized)
    return;
  is_initialized = true;
  // We are not ready to handle interceptors yet.
  ScopedIgnoreInterceptors ignore;
  SanitizerToolName = "ThreadSanitizer";
  // Install tool-specific callbacks in sanitizer_common.
  SetCheckUnwindCallback(CheckUnwind);

  ctx = new(ctx_placeholder) Context;
  const char *env_name = SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS";
  const char *options = GetEnv(env_name);
  CacheBinaryName();
  CheckASLR();
  InitializeFlags(&ctx->flags, options, env_name);
  AvoidCVE_2016_2143();
  __sanitizer::InitializePlatformEarly();
  __tsan::InitializePlatformEarly();

#if !SANITIZER_GO
  // Re-exec ourselves if we need to set additional env or command line args.
  MaybeReexec();

  InitializeAllocator();
  ReplaceSystemMalloc();
#endif
  if (common_flags()->detect_deadlocks)
    ctx->dd = DDetector::Create(flags());
  Processor *proc = ProcCreate();
  ProcWire(proc, thr);
  InitializeInterceptors();
  InitializePlatform();
  InitializeDynamicAnnotations();
#if !SANITIZER_GO
  InitializeShadowMemory();
  InitializeAllocatorLate();
  InstallDeadlySignalHandlers(TsanOnDeadlySignal);
#endif
  // Setup correct file descriptor for error reports.
  __sanitizer_set_report_path(common_flags()->log_path);
  InitializeSuppressions();
#if !SANITIZER_GO
  InitializeLibIgnore();
  Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer);
#endif

  VPrintf(1, "***** Running under ThreadSanitizer v3 (pid %d) *****\n",
          (int)internal_getpid());

  // Initialize thread 0.
  Tid tid = ThreadCreate(nullptr, 0, 0, true);
  CHECK_EQ(tid, kMainTid);
  ThreadStart(thr, tid, GetTid(), ThreadType::Regular);
#if TSAN_CONTAINS_UBSAN
  __ubsan::InitAsPlugin();
#endif

#if !SANITIZER_GO
  Symbolizer::LateInitialize();
  InitializeMemoryProfiler();
#endif
  ctx->initialized = true;

  if (flags()->stop_on_start) {
    Printf("ThreadSanitizer is suspended at startup (pid %d)."
           " Call __tsan_resume().\n",
           (int)internal_getpid());
    while (__tsan_resumed == 0) {}
  }

  OnInitialize();
}

void MaybeSpawnBackgroundThread() {
  // On MIPS, TSan initialization is run before
  // __pthread_initialize_minimal_internal() is finished, so we can not spawn
  // new threads.
#if !SANITIZER_GO && !defined(__mips__)
  static atomic_uint32_t bg_thread = {};
  if (atomic_load(&bg_thread, memory_order_relaxed) == 0 &&
      atomic_exchange(&bg_thread, 1, memory_order_relaxed) == 0) {
    StartBackgroundThread();
    SetSandboxingCallback(StopBackgroundThread);
  }
#endif
}

int Finalize(ThreadState *thr) {
  bool failed = false;

  if (common_flags()->print_module_map == 1)
    DumpProcessMap();

  if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1)
    internal_usleep(u64(flags()->atexit_sleep_ms) * 1000);

  {
    // Wait for pending reports.
    ScopedErrorReportLock lock;
  }

#if !SANITIZER_GO
  if (Verbosity()) AllocatorPrintStats();
#endif

  ThreadFinalize(thr);

  if (ctx->nreported) {
    failed = true;
#if !SANITIZER_GO
    Printf("ThreadSanitizer: reported %d warnings\n", ctx->nreported);
#else
    Printf("Found %d data race(s)\n", ctx->nreported);
#endif
  }

  if (common_flags()->print_suppressions)
    PrintMatchedSuppressions();

  failed = OnFinalize(failed);

  return failed ? common_flags()->exitcode : 0;
}

#if !SANITIZER_GO
void ForkBefore(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS {
  // Detaching from the slot makes OnUserFree skip writing to the shadow.
  // The slot will be locked so any attempts to use it will deadlock anyway.
  SlotDetach(thr);
  ctx->multi_slot_mtx.Lock();
  for (auto& slot : ctx->slots) slot.mtx.Lock();
  ctx->thread_registry.Lock();
  ctx->slot_mtx.Lock();
  ScopedErrorReportLock::Lock();
  // Suppress all reports in the pthread_atfork callbacks.
  // Reports will deadlock on the report_mtx.
  // We could ignore sync operations as well,
  // but so far it's unclear if it will do more good or harm.
  // Unnecessarily ignoring things can lead to false positives later.
  thr->suppress_reports++;
  // On OS X, REAL(fork) can call intercepted functions (OSSpinLockLock), and
  // we'll assert in CheckNoLocks() unless we ignore interceptors.
  // On OS X libSystem_atfork_prepare/parent/child callbacks are called
  // after/before our callbacks and they call free.
  thr->ignore_interceptors++;
  // Disables memory write in OnUserFree.
  thr->ignore_reads_and_writes++;

  __tsan_test_only_on_fork();
}

static void ForkAfter(ThreadState* thr) NO_THREAD_SAFETY_ANALYSIS {
  thr->suppress_reports--;  // Enabled in ForkBefore.
  thr->ignore_interceptors--;
  thr->ignore_reads_and_writes--;
  ScopedErrorReportLock::Unlock();
  ctx->slot_mtx.Unlock();
  ctx->thread_registry.Unlock();
  for (auto& slot : ctx->slots) slot.mtx.Unlock();
  ctx->multi_slot_mtx.Unlock();
  SlotAttachAndLock(thr);
  SlotUnlock(thr);
}

void ForkParentAfter(ThreadState* thr, uptr pc) { ForkAfter(thr); }

void ForkChildAfter(ThreadState* thr, uptr pc, bool start_thread) {
  ForkAfter(thr);
  u32 nthread = ThreadCount(thr);
  VPrintf(1,
          "ThreadSanitizer: forked new process with pid %d,"
          " parent had %d threads\n",
          (int)internal_getpid(), (int)nthread);
  if (nthread == 1) {
    if (start_thread)
      StartBackgroundThread();
  } else {
    // We've just forked a multi-threaded process. We cannot reasonably function
    // after that (some mutexes may be locked before fork). So just enable
    // ignores for everything in the hope that we will exec soon.
    ctx->after_multithreaded_fork = true;
    thr->ignore_interceptors++;
    thr->suppress_reports++;
    ThreadIgnoreBegin(thr, pc);
    ThreadIgnoreSyncBegin(thr, pc);
  }
}
#endif

#if SANITIZER_GO
NOINLINE
void GrowShadowStack(ThreadState *thr) {
  const int sz = thr->shadow_stack_end - thr->shadow_stack;
  const int newsz = 2 * sz;
  auto *newstack = (uptr *)Alloc(newsz * sizeof(uptr));
  internal_memcpy(newstack, thr->shadow_stack, sz * sizeof(uptr));
  Free(thr->shadow_stack);
  thr->shadow_stack = newstack;
  thr->shadow_stack_pos = newstack + sz;
  thr->shadow_stack_end = newstack + newsz;
}
#endif

StackID CurrentStackId(ThreadState *thr, uptr pc) {
#if !SANITIZER_GO
  if (!thr->is_inited)  // May happen during bootstrap.
    return kInvalidStackID;
#endif
  if (pc != 0) {
#if !SANITIZER_GO
    DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end);
#else
    if (thr->shadow_stack_pos == thr->shadow_stack_end)
      GrowShadowStack(thr);
#endif
    thr->shadow_stack_pos[0] = pc;
    thr->shadow_stack_pos++;
  }
  StackID id = StackDepotPut(
      StackTrace(thr->shadow_stack, thr->shadow_stack_pos - thr->shadow_stack));
  if (pc != 0)
    thr->shadow_stack_pos--;
  return id;
}

static bool TraceSkipGap(ThreadState* thr) {
  Trace *trace = &thr->tctx->trace;
  Event *pos = reinterpret_cast<Event *>(atomic_load_relaxed(&thr->trace_pos));
  DCHECK_EQ(reinterpret_cast<uptr>(pos + 1) & TracePart::kAlignment, 0);
  auto *part = trace->parts.Back();
  DPrintf("#%d: TraceSwitchPart enter trace=%p parts=%p-%p pos=%p\n", thr->tid,
          trace, trace->parts.Front(), part, pos);
  if (!part)
    return false;
  // We can get here when we still have space in the current trace part.
  // The fast-path check in TraceAcquire has false positives in the middle of
  // the part. Check if we are indeed at the end of the current part or not,
  // and fill any gaps with NopEvent's.
  Event* end = &part->events[TracePart::kSize];
  DCHECK_GE(pos, &part->events[0]);
  DCHECK_LE(pos, end);
  if (pos + 1 < end) {
    if ((reinterpret_cast<uptr>(pos) & TracePart::kAlignment) ==
        TracePart::kAlignment)
      *pos++ = NopEvent;
    *pos++ = NopEvent;
    DCHECK_LE(pos + 2, end);
    atomic_store_relaxed(&thr->trace_pos, reinterpret_cast<uptr>(pos));
    return true;
  }
  // We are indeed at the end.
  for (; pos < end; pos++) *pos = NopEvent;
  return false;
}

NOINLINE
void TraceSwitchPart(ThreadState* thr) {
  if (TraceSkipGap(thr))
    return;
#if !SANITIZER_GO
  if (ctx->after_multithreaded_fork) {
    // We just need to survive till exec.
    TracePart* part = thr->tctx->trace.parts.Back();
    if (part) {
      atomic_store_relaxed(&thr->trace_pos,
                           reinterpret_cast<uptr>(&part->events[0]));
      return;
    }
  }
#endif
  TraceSwitchPartImpl(thr);
}

void TraceSwitchPartImpl(ThreadState* thr) {
  SlotLocker locker(thr, true);
  Trace* trace = &thr->tctx->trace;
  TracePart* part = TracePartAlloc(thr);
  part->trace = trace;
  thr->trace_prev_pc = 0;
  TracePart* recycle = nullptr;
  // Keep roughly half of parts local to the thread
  // (not queued into the recycle queue).
  uptr local_parts = (Trace::kMinParts + flags()->history_size + 1) / 2;
  {
    Lock lock(&trace->mtx);
    if (trace->parts.Empty())
      trace->local_head = part;
    if (trace->parts.Size() >= local_parts) {
      recycle = trace->local_head;
      trace->local_head = trace->parts.Next(recycle);
    }
    trace->parts.PushBack(part);
    atomic_store_relaxed(&thr->trace_pos,
                         reinterpret_cast<uptr>(&part->events[0]));
  }
  // Make this part self-sufficient by restoring the current stack
  // and mutex set in the beginning of the trace.
  TraceTime(thr);
  {
    // Pathologically large stacks may not fit into the part.
    // In these cases we log only fixed number of top frames.
    const uptr kMaxFrames = 1000;
    // Sanity check that kMaxFrames won't consume the whole part.
    static_assert(kMaxFrames < TracePart::kSize / 2, "kMaxFrames is too big");
    uptr* pos = Max(&thr->shadow_stack[0], thr->shadow_stack_pos - kMaxFrames);
    for (; pos < thr->shadow_stack_pos; pos++) {
      if (TryTraceFunc(thr, *pos))
        continue;
      CHECK(TraceSkipGap(thr));
      CHECK(TryTraceFunc(thr, *pos));
    }
  }
  for (uptr i = 0; i < thr->mset.Size(); i++) {
    MutexSet::Desc d = thr->mset.Get(i);
    for (uptr i = 0; i < d.count; i++)
      TraceMutexLock(thr, d.write ? EventType::kLock : EventType::kRLock, 0,
                     d.addr, d.stack_id);
  }
  {
    Lock lock(&ctx->slot_mtx);
    ctx->slot_queue.Remove(thr->slot);
    ctx->slot_queue.PushBack(thr->slot);
    if (recycle)
      ctx->trace_part_recycle.PushBack(recycle);
  }
  DPrintf("#%d: TraceSwitchPart exit parts=%p-%p pos=0x%zx\n", thr->tid,
          trace->parts.Front(), trace->parts.Back(),
          atomic_load_relaxed(&thr->trace_pos));
}

#if !SANITIZER_GO
extern "C" void __tsan_trace_switch() {}

extern "C" void __tsan_report_race() {}
#endif

void ThreadIgnoreBegin(ThreadState* thr, uptr pc) {
  DPrintf("#%d: ThreadIgnoreBegin\n", thr->tid);
  thr->ignore_reads_and_writes++;
  CHECK_GT(thr->ignore_reads_and_writes, 0);
  thr->fast_state.SetIgnoreBit();
#if !SANITIZER_GO
  if (pc && !ctx->after_multithreaded_fork)
    thr->mop_ignore_set.Add(CurrentStackId(thr, pc));
#endif
}

void ThreadIgnoreEnd(ThreadState *thr) {
  DPrintf("#%d: ThreadIgnoreEnd\n", thr->tid);
  CHECK_GT(thr->ignore_reads_and_writes, 0);
  thr->ignore_reads_and_writes--;
  if (thr->ignore_reads_and_writes == 0) {
    thr->fast_state.ClearIgnoreBit();
#if !SANITIZER_GO
    thr->mop_ignore_set.Reset();
#endif
  }
}

#if !SANITIZER_GO
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
uptr __tsan_testonly_shadow_stack_current_size() {
  ThreadState *thr = cur_thread();
  return thr->shadow_stack_pos - thr->shadow_stack;
}
#endif

void ThreadIgnoreSyncBegin(ThreadState *thr, uptr pc) {
  DPrintf("#%d: ThreadIgnoreSyncBegin\n", thr->tid);
  thr->ignore_sync++;
  CHECK_GT(thr->ignore_sync, 0);
#if !SANITIZER_GO
  if (pc && !ctx->after_multithreaded_fork)
    thr->sync_ignore_set.Add(CurrentStackId(thr, pc));
#endif
}

void ThreadIgnoreSyncEnd(ThreadState *thr) {
  DPrintf("#%d: ThreadIgnoreSyncEnd\n", thr->tid);
  CHECK_GT(thr->ignore_sync, 0);
  thr->ignore_sync--;
#if !SANITIZER_GO
  if (thr->ignore_sync == 0)
    thr->sync_ignore_set.Reset();
#endif
}

bool MD5Hash::operator==(const MD5Hash &other) const {
  return hash[0] == other.hash[0] && hash[1] == other.hash[1];
}

#if SANITIZER_DEBUG
void build_consistency_debug() {}
#else
void build_consistency_release() {}
#endif
}  // namespace __tsan

#if SANITIZER_CHECK_DEADLOCKS
namespace __sanitizer {
using namespace __tsan;
MutexMeta mutex_meta[] = {
    {MutexInvalid, "Invalid", {}},
    {MutexThreadRegistry,
     "ThreadRegistry",
     {MutexTypeSlots, MutexTypeTrace, MutexTypeReport}},
    {MutexTypeReport, "Report", {MutexTypeTrace}},
    {MutexTypeSyncVar, "SyncVar", {MutexTypeReport, MutexTypeTrace}},
    {MutexTypeAnnotations, "Annotations", {MutexLeaf}},
    {MutexTypeAtExit, "AtExit", {}},
    {MutexTypeFired, "Fired", {MutexLeaf}},
    {MutexTypeRacy, "Racy", {MutexLeaf}},
    {MutexTypeGlobalProc, "GlobalProc", {MutexTypeSlot, MutexTypeSlots}},
    {MutexTypeTrace, "Trace", {}},
    {MutexTypeSlot,
     "Slot",
     {MutexMulti, MutexTypeTrace, MutexTypeSyncVar, MutexThreadRegistry,
      MutexTypeSlots}},
    {MutexTypeSlots, "Slots", {MutexTypeTrace, MutexTypeReport}},
    {MutexTypeMultiSlot, "MultiSlot", {MutexTypeSlot, MutexTypeSlots}},
    {},
};

void PrintMutexPC(uptr pc) { StackTrace(&pc, 1).Print(); }

}  // namespace __sanitizer
#endif
