lsan_thread.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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 ThreadContextBase *CreateThreadContext(u32 tid) {
  24. void *mem = MmapOrDie(sizeof(ThreadContext), "ThreadContext");
  25. return new (mem) ThreadContext(tid);
  26. }
  27. void InitializeThreadRegistry() {
  28. static ALIGNED(64) char thread_registry_placeholder[sizeof(ThreadRegistry)];
  29. thread_registry =
  30. new (thread_registry_placeholder) ThreadRegistry(CreateThreadContext);
  31. }
  32. ThreadContextLsanBase::ThreadContextLsanBase(int tid)
  33. : ThreadContextBase(tid) {}
  34. void ThreadContextLsanBase::OnFinished() {
  35. AllocatorThreadFinish();
  36. DTLS_Destroy();
  37. }
  38. u32 ThreadCreate(u32 parent_tid, bool detached, void *arg) {
  39. return thread_registry->CreateThread(0, detached, parent_tid, arg);
  40. }
  41. void ThreadContextLsanBase::ThreadStart(u32 tid, tid_t os_id,
  42. ThreadType thread_type, void *arg) {
  43. thread_registry->StartThread(tid, os_id, thread_type, arg);
  44. SetCurrentThread(tid);
  45. }
  46. void ThreadFinish() {
  47. thread_registry->FinishThread(GetCurrentThread());
  48. SetCurrentThread(kInvalidTid);
  49. }
  50. struct ThreadsGuard {
  51. ThreadsGuard() {
  52. LockThreadRegistry();
  53. }
  54. ~ThreadsGuard() {
  55. UnlockThreadRegistry();
  56. }
  57. };
  58. ThreadContext *CurrentThreadContext() {
  59. if (!thread_registry)
  60. return nullptr;
  61. if (GetCurrentThread() == kInvalidTid)
  62. return nullptr;
  63. ThreadsGuard lock;
  64. return (ThreadContext *)thread_registry->GetThreadLocked(GetCurrentThread());
  65. }
  66. void EnsureMainThreadIDIsCorrect() {
  67. if (GetCurrentThread() == kMainTid)
  68. CurrentThreadContext()->os_id = GetTid();
  69. }
  70. ///// Interface to the common LSan module. /////
  71. void GetThreadExtraStackRangesLocked(tid_t os_id,
  72. InternalMmapVector<Range> *ranges) {}
  73. void GetThreadExtraStackRangesLocked(InternalMmapVector<Range> *ranges) {}
  74. void LockThreadRegistry() { thread_registry->Lock(); }
  75. void UnlockThreadRegistry() { thread_registry->Unlock(); }
  76. ThreadRegistry *GetLsanThreadRegistryLocked() {
  77. thread_registry->CheckLocked();
  78. return thread_registry;
  79. }
  80. void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
  81. GetLsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(
  82. [](ThreadContextBase *tctx, void *threads) {
  83. if (tctx->status == ThreadStatusRunning) {
  84. reinterpret_cast<InternalMmapVector<tid_t> *>(threads)->push_back(
  85. tctx->os_id);
  86. }
  87. },
  88. threads);
  89. }
  90. } // namespace __lsan