Path: blob/main/contrib/llvm-project/compiler-rt/lib/lsan/lsan_thread.cpp
35234 views
//=-- lsan_thread.cpp -----------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of LeakSanitizer.9// See lsan_thread.h for details.10//11//===----------------------------------------------------------------------===//1213#include "lsan_thread.h"1415#include "lsan.h"16#include "lsan_allocator.h"17#include "lsan_common.h"18#include "sanitizer_common/sanitizer_common.h"19#include "sanitizer_common/sanitizer_placement_new.h"20#include "sanitizer_common/sanitizer_thread_registry.h"21#include "sanitizer_common/sanitizer_tls_get_addr.h"2223namespace __lsan {2425static ThreadRegistry *thread_registry;26static ThreadArgRetval *thread_arg_retval;2728static Mutex mu_for_thread_context;29static LowLevelAllocator allocator_for_thread_context;3031static ThreadContextBase *CreateThreadContext(u32 tid) {32Lock lock(&mu_for_thread_context);33return new (allocator_for_thread_context) ThreadContext(tid);34}3536void InitializeThreads() {37alignas(alignof(ThreadRegistry)) static char38thread_registry_placeholder[sizeof(ThreadRegistry)];39thread_registry =40new (thread_registry_placeholder) ThreadRegistry(CreateThreadContext);4142alignas(alignof(ThreadArgRetval)) static char43thread_arg_retval_placeholder[sizeof(ThreadArgRetval)];44thread_arg_retval = new (thread_arg_retval_placeholder) ThreadArgRetval();45}4647ThreadArgRetval &GetThreadArgRetval() { return *thread_arg_retval; }4849ThreadContextLsanBase::ThreadContextLsanBase(int tid)50: ThreadContextBase(tid) {}5152void ThreadContextLsanBase::OnStarted(void *arg) {53SetCurrentThread(this);54AllocatorThreadStart();55}5657void ThreadContextLsanBase::OnFinished() {58AllocatorThreadFinish();59DTLS_Destroy();60SetCurrentThread(nullptr);61}6263u32 ThreadCreate(u32 parent_tid, bool detached, void *arg) {64return thread_registry->CreateThread(0, detached, parent_tid, arg);65}6667void ThreadContextLsanBase::ThreadStart(u32 tid, tid_t os_id,68ThreadType thread_type, void *arg) {69thread_registry->StartThread(tid, os_id, thread_type, arg);70}7172void ThreadFinish() { thread_registry->FinishThread(GetCurrentThreadId()); }7374void EnsureMainThreadIDIsCorrect() {75if (GetCurrentThreadId() == kMainTid)76GetCurrentThread()->os_id = GetTid();77}7879///// Interface to the common LSan module. /////8081void GetThreadExtraStackRangesLocked(tid_t os_id,82InternalMmapVector<Range> *ranges) {}83void GetThreadExtraStackRangesLocked(InternalMmapVector<Range> *ranges) {}8485void LockThreads() {86thread_registry->Lock();87thread_arg_retval->Lock();88}8990void UnlockThreads() {91thread_arg_retval->Unlock();92thread_registry->Unlock();93}9495ThreadRegistry *GetLsanThreadRegistryLocked() {96thread_registry->CheckLocked();97return thread_registry;98}99100void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {101GetLsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(102[](ThreadContextBase *tctx, void *threads) {103if (tctx->status == ThreadStatusRunning) {104reinterpret_cast<InternalMmapVector<tid_t> *>(threads)->push_back(105tctx->os_id);106}107},108threads);109}110111void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {112GetThreadArgRetval().GetAllPtrsLocked(ptrs);113}114115} // namespace __lsan116117118