123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- //=-- lsan_thread.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 LeakSanitizer.
- // See lsan_thread.h for details.
- //
- //===----------------------------------------------------------------------===//
- #include "lsan_thread.h"
- #include "lsan.h"
- #include "lsan_allocator.h"
- #include "lsan_common.h"
- #include "sanitizer_common/sanitizer_common.h"
- #include "sanitizer_common/sanitizer_placement_new.h"
- #include "sanitizer_common/sanitizer_thread_registry.h"
- #include "sanitizer_common/sanitizer_tls_get_addr.h"
- namespace __lsan {
- static ThreadRegistry *thread_registry;
- static ThreadArgRetval *thread_arg_retval;
- static Mutex mu_for_thread_context;
- static LowLevelAllocator allocator_for_thread_context;
- static ThreadContextBase *CreateThreadContext(u32 tid) {
- Lock lock(&mu_for_thread_context);
- return new (allocator_for_thread_context) ThreadContext(tid);
- }
- void InitializeThreads() {
- static ALIGNED(alignof(
- ThreadRegistry)) char thread_registry_placeholder[sizeof(ThreadRegistry)];
- thread_registry =
- new (thread_registry_placeholder) ThreadRegistry(CreateThreadContext);
- static ALIGNED(alignof(ThreadArgRetval)) char
- thread_arg_retval_placeholder[sizeof(ThreadArgRetval)];
- thread_arg_retval = new (thread_arg_retval_placeholder) ThreadArgRetval();
- }
- ThreadArgRetval &GetThreadArgRetval() { return *thread_arg_retval; }
- ThreadContextLsanBase::ThreadContextLsanBase(int tid)
- : ThreadContextBase(tid) {}
- void ThreadContextLsanBase::OnStarted(void *arg) {
- SetCurrentThread(this);
- AllocatorThreadStart();
- }
- void ThreadContextLsanBase::OnFinished() {
- AllocatorThreadFinish();
- DTLS_Destroy();
- SetCurrentThread(nullptr);
- }
- u32 ThreadCreate(u32 parent_tid, bool detached, void *arg) {
- return thread_registry->CreateThread(0, detached, parent_tid, arg);
- }
- void ThreadContextLsanBase::ThreadStart(u32 tid, tid_t os_id,
- ThreadType thread_type, void *arg) {
- thread_registry->StartThread(tid, os_id, thread_type, arg);
- }
- void ThreadFinish() { thread_registry->FinishThread(GetCurrentThreadId()); }
- void EnsureMainThreadIDIsCorrect() {
- if (GetCurrentThreadId() == kMainTid)
- GetCurrentThread()->os_id = GetTid();
- }
- ///// Interface to the common LSan module. /////
- void GetThreadExtraStackRangesLocked(tid_t os_id,
- InternalMmapVector<Range> *ranges) {}
- void GetThreadExtraStackRangesLocked(InternalMmapVector<Range> *ranges) {}
- void LockThreads() {
- thread_registry->Lock();
- thread_arg_retval->Lock();
- }
- void UnlockThreads() {
- thread_arg_retval->Unlock();
- thread_registry->Unlock();
- }
- ThreadRegistry *GetLsanThreadRegistryLocked() {
- thread_registry->CheckLocked();
- return thread_registry;
- }
- void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
- GetLsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(
- [](ThreadContextBase *tctx, void *threads) {
- if (tctx->status == ThreadStatusRunning) {
- reinterpret_cast<InternalMmapVector<tid_t> *>(threads)->push_back(
- tctx->os_id);
- }
- },
- threads);
- }
- void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {
- GetThreadArgRetval().GetAllPtrsLocked(ptrs);
- }
- } // namespace __lsan
|