brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · 22eb9ee Raw
124 lines · cpp
1//=-- lsan_thread.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-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of LeakSanitizer.10// See lsan_thread.h for details.11//12//===----------------------------------------------------------------------===//13 14#include "lsan_thread.h"15 16#include "lsan.h"17#include "lsan_allocator.h"18#include "lsan_common.h"19#include "sanitizer_common/sanitizer_common.h"20#include "sanitizer_common/sanitizer_placement_new.h"21#include "sanitizer_common/sanitizer_thread_history.h"22#include "sanitizer_common/sanitizer_thread_registry.h"23#include "sanitizer_common/sanitizer_tls_get_addr.h"24 25namespace __lsan {26 27static ThreadRegistry *thread_registry;28static ThreadArgRetval *thread_arg_retval;29 30static Mutex mu_for_thread_context;31static LowLevelAllocator allocator_for_thread_context;32 33static ThreadContextBase *CreateThreadContext(u32 tid) {34  Lock lock(&mu_for_thread_context);35  return new (allocator_for_thread_context) ThreadContext(tid);36}37 38void InitializeThreads() {39  alignas(alignof(ThreadRegistry)) static char40      thread_registry_placeholder[sizeof(ThreadRegistry)];41  thread_registry =42      new (thread_registry_placeholder) ThreadRegistry(CreateThreadContext);43 44  alignas(alignof(ThreadArgRetval)) static char45      thread_arg_retval_placeholder[sizeof(ThreadArgRetval)];46  thread_arg_retval = new (thread_arg_retval_placeholder) ThreadArgRetval();47}48 49ThreadArgRetval &GetThreadArgRetval() { return *thread_arg_retval; }50 51ThreadContextLsanBase::ThreadContextLsanBase(int tid)52    : ThreadContextBase(tid) {}53 54void ThreadContextLsanBase::OnStarted(void *arg) {55  SetCurrentThread(this);56  AllocatorThreadStart();57}58 59void ThreadContextLsanBase::OnFinished() {60  AllocatorThreadFinish();61  DTLS_Destroy();62  SetCurrentThread(nullptr);63}64 65u32 ThreadCreate(u32 parent_tid, bool detached, void *arg) {66  return thread_registry->CreateThread(0, detached, parent_tid, arg);67}68 69void ThreadContextLsanBase::ThreadStart(u32 tid, ThreadID os_id,70                                        ThreadType thread_type, void *arg) {71  thread_registry->StartThread(tid, os_id, thread_type, arg);72}73 74void ThreadFinish() { thread_registry->FinishThread(GetCurrentThreadId()); }75 76void EnsureMainThreadIDIsCorrect() {77  if (GetCurrentThreadId() == kMainTid)78    GetCurrentThread()->os_id = GetTid();79}80 81///// Interface to the common LSan module. /////82 83void GetThreadExtraStackRangesLocked(ThreadID os_id,84                                     InternalMmapVector<Range> *ranges) {}85void GetThreadExtraStackRangesLocked(InternalMmapVector<Range> *ranges) {}86 87void LockThreads() {88  thread_registry->Lock();89  thread_arg_retval->Lock();90}91 92void UnlockThreads() {93  thread_arg_retval->Unlock();94  thread_registry->Unlock();95}96 97ThreadRegistry *GetLsanThreadRegistryLocked() {98  thread_registry->CheckLocked();99  return thread_registry;100}101 102void GetRunningThreadsLocked(InternalMmapVector<ThreadID> *threads) {103  GetLsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(104      [](ThreadContextBase *tctx, void *threads) {105        if (tctx->status == ThreadStatusRunning) {106          reinterpret_cast<InternalMmapVector<ThreadID> *>(threads)->push_back(107              tctx->os_id);108        }109      },110      threads);111}112 113void PrintThreads() {114  InternalScopedString out;115  PrintThreadHistory(*thread_registry, out);116  Report("%s\n", out.data());117}118 119void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {120  GetThreadArgRetval().GetAllPtrsLocked(ptrs);121}122 123}  // namespace __lsan124