lsan_thread.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file is a part of LeakSanitizer.
  10. // See lsan_thread.h for details.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "lsan_thread.h"
  14. #include "lsan.h"
  15. #include "lsan_allocator.h"
  16. #include "lsan_common.h"
  17. #include "sanitizer_common/sanitizer_common.h"
  18. #include "sanitizer_common/sanitizer_placement_new.h"
  19. #include "sanitizer_common/sanitizer_thread_registry.h"
  20. #include "sanitizer_common/sanitizer_tls_get_addr.h"
  21. namespace __lsan {
  22. static ThreadRegistry *thread_registry;
  23. static ThreadArgRetval *thread_arg_retval;
  24. static Mutex mu_for_thread_context;
  25. static LowLevelAllocator allocator_for_thread_context;
  26. static ThreadContextBase *CreateThreadContext(u32 tid) {
  27. Lock lock(&mu_for_thread_context);
  28. return new (allocator_for_thread_context) ThreadContext(tid);
  29. }
  30. void InitializeThreads() {
  31. static ALIGNED(alignof(
  32. ThreadRegistry)) char thread_registry_placeholder[sizeof(ThreadRegistry)];
  33. thread_registry =
  34. new (thread_registry_placeholder) ThreadRegistry(CreateThreadContext);
  35. static ALIGNED(alignof(ThreadArgRetval)) char
  36. thread_arg_retval_placeholder[sizeof(ThreadArgRetval)];
  37. thread_arg_retval = new (thread_arg_retval_placeholder) ThreadArgRetval();
  38. }
  39. ThreadArgRetval &GetThreadArgRetval() { return *thread_arg_retval; }
  40. ThreadContextLsanBase::ThreadContextLsanBase(int tid)
  41. : ThreadContextBase(tid) {}
  42. void ThreadContextLsanBase::OnStarted(void *arg) {
  43. SetCurrentThread(this);
  44. AllocatorThreadStart();
  45. }
  46. void ThreadContextLsanBase::OnFinished() {
  47. AllocatorThreadFinish();
  48. DTLS_Destroy();
  49. SetCurrentThread(nullptr);
  50. }
  51. u32 ThreadCreate(u32 parent_tid, bool detached, void *arg) {
  52. return thread_registry->CreateThread(0, detached, parent_tid, arg);
  53. }
  54. void ThreadContextLsanBase::ThreadStart(u32 tid, tid_t os_id,
  55. ThreadType thread_type, void *arg) {
  56. thread_registry->StartThread(tid, os_id, thread_type, arg);
  57. }
  58. void ThreadFinish() { thread_registry->FinishThread(GetCurrentThreadId()); }
  59. void EnsureMainThreadIDIsCorrect() {
  60. if (GetCurrentThreadId() == kMainTid)
  61. GetCurrentThread()->os_id = GetTid();
  62. }
  63. ///// Interface to the common LSan module. /////
  64. void GetThreadExtraStackRangesLocked(tid_t os_id,
  65. InternalMmapVector<Range> *ranges) {}
  66. void GetThreadExtraStackRangesLocked(InternalMmapVector<Range> *ranges) {}
  67. void LockThreads() {
  68. thread_registry->Lock();
  69. thread_arg_retval->Lock();
  70. }
  71. void UnlockThreads() {
  72. thread_arg_retval->Unlock();
  73. thread_registry->Unlock();
  74. }
  75. ThreadRegistry *GetLsanThreadRegistryLocked() {
  76. thread_registry->CheckLocked();
  77. return thread_registry;
  78. }
  79. void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
  80. GetLsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(
  81. [](ThreadContextBase *tctx, void *threads) {
  82. if (tctx->status == ThreadStatusRunning) {
  83. reinterpret_cast<InternalMmapVector<tid_t> *>(threads)->push_back(
  84. tctx->os_id);
  85. }
  86. },
  87. threads);
  88. }
  89. void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {
  90. GetThreadArgRetval().GetAllPtrsLocked(ptrs);
  91. }
  92. } // namespace __lsan