(root)/
gcc-13.2.0/
libsanitizer/
asan/
asan_thread.h
       1  //===-- asan_thread.h -------------------------------------------*- C++ -*-===//
       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 AddressSanitizer, an address sanity checker.
      10  //
      11  // ASan-private header for asan_thread.cpp.
      12  //===----------------------------------------------------------------------===//
      13  
      14  #ifndef ASAN_THREAD_H
      15  #define ASAN_THREAD_H
      16  
      17  #include "asan_allocator.h"
      18  #include "asan_internal.h"
      19  #include "asan_fake_stack.h"
      20  #include "asan_stats.h"
      21  #include "sanitizer_common/sanitizer_common.h"
      22  #include "sanitizer_common/sanitizer_libc.h"
      23  #include "sanitizer_common/sanitizer_thread_registry.h"
      24  
      25  namespace __sanitizer {
      26  struct DTLS;
      27  }  // namespace __sanitizer
      28  
      29  namespace __asan {
      30  
      31  class AsanThread;
      32  
      33  // These objects are created for every thread and are never deleted,
      34  // so we can find them by tid even if the thread is long dead.
      35  class AsanThreadContext final : public ThreadContextBase {
      36   public:
      37    explicit AsanThreadContext(int tid)
      38        : ThreadContextBase(tid), announced(false),
      39          destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),
      40          thread(nullptr) {}
      41    bool announced;
      42    u8 destructor_iterations;
      43    u32 stack_id;
      44    AsanThread *thread;
      45  
      46    void OnCreated(void *arg) override;
      47    void OnFinished() override;
      48  
      49    struct CreateThreadContextArgs {
      50      AsanThread *thread;
      51      StackTrace *stack;
      52    };
      53  };
      54  
      55  // AsanThreadContext objects are never freed, so we need many of them.
      56  COMPILER_CHECK(sizeof(AsanThreadContext) <= 256);
      57  
      58  // AsanThread are stored in TSD and destroyed when the thread dies.
      59  class AsanThread {
      60   public:
      61    static AsanThread *Create(thread_callback_t start_routine, void *arg,
      62                              u32 parent_tid, StackTrace *stack, bool detached);
      63    static void TSDDtor(void *tsd);
      64    void Destroy();
      65  
      66    struct InitOptions;
      67    void Init(const InitOptions *options = nullptr);
      68  
      69    thread_return_t ThreadStart(tid_t os_id);
      70  
      71    uptr stack_top();
      72    uptr stack_bottom();
      73    uptr stack_size();
      74    uptr tls_begin() { return tls_begin_; }
      75    uptr tls_end() { return tls_end_; }
      76    DTLS *dtls() { return dtls_; }
      77    u32 tid() { return context_->tid; }
      78    AsanThreadContext *context() { return context_; }
      79    void set_context(AsanThreadContext *context) { context_ = context; }
      80  
      81    struct StackFrameAccess {
      82      uptr offset;
      83      uptr frame_pc;
      84      const char *frame_descr;
      85    };
      86    bool GetStackFrameAccessByAddr(uptr addr, StackFrameAccess *access);
      87  
      88    // Returns a pointer to the start of the stack variable's shadow memory.
      89    uptr GetStackVariableShadowStart(uptr addr);
      90  
      91    bool AddrIsInStack(uptr addr);
      92  
      93    void DeleteFakeStack(int tid) {
      94      if (!fake_stack_) return;
      95      FakeStack *t = fake_stack_;
      96      fake_stack_ = nullptr;
      97      SetTLSFakeStack(nullptr);
      98      t->Destroy(tid);
      99    }
     100  
     101    void StartSwitchFiber(FakeStack **fake_stack_save, uptr bottom, uptr size);
     102    void FinishSwitchFiber(FakeStack *fake_stack_save, uptr *bottom_old,
     103                           uptr *size_old);
     104  
     105    FakeStack *get_fake_stack() {
     106      if (atomic_load(&stack_switching_, memory_order_relaxed))
     107        return nullptr;
     108      if (reinterpret_cast<uptr>(fake_stack_) <= 1)
     109        return nullptr;
     110      return fake_stack_;
     111    }
     112  
     113    FakeStack *get_or_create_fake_stack() {
     114      if (atomic_load(&stack_switching_, memory_order_relaxed))
     115        return nullptr;
     116      if (reinterpret_cast<uptr>(fake_stack_) <= 1)
     117        return AsyncSignalSafeLazyInitFakeStack();
     118      return fake_stack_;
     119    }
     120  
     121    // True is this thread is currently unwinding stack (i.e. collecting a stack
     122    // trace). Used to prevent deadlocks on platforms where libc unwinder calls
     123    // malloc internally. See PR17116 for more details.
     124    bool isUnwinding() const { return unwinding_; }
     125    void setUnwinding(bool b) { unwinding_ = b; }
     126  
     127    AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
     128    AsanStats &stats() { return stats_; }
     129  
     130    void *extra_spill_area() { return &extra_spill_area_; }
     131  
     132    void *get_arg() { return arg_; }
     133  
     134   private:
     135    // NOTE: There is no AsanThread constructor. It is allocated
     136    // via mmap() and *must* be valid in zero-initialized state.
     137  
     138    void SetThreadStackAndTls(const InitOptions *options);
     139  
     140    void ClearShadowForThreadStackAndTLS();
     141    FakeStack *AsyncSignalSafeLazyInitFakeStack();
     142  
     143    struct StackBounds {
     144      uptr bottom;
     145      uptr top;
     146    };
     147    StackBounds GetStackBounds() const;
     148  
     149    AsanThreadContext *context_;
     150    thread_callback_t start_routine_;
     151    void *arg_;
     152  
     153    uptr stack_top_;
     154    uptr stack_bottom_;
     155    // these variables are used when the thread is about to switch stack
     156    uptr next_stack_top_;
     157    uptr next_stack_bottom_;
     158    // true if switching is in progress
     159    atomic_uint8_t stack_switching_;
     160  
     161    uptr tls_begin_;
     162    uptr tls_end_;
     163    DTLS *dtls_;
     164  
     165    FakeStack *fake_stack_;
     166    AsanThreadLocalMallocStorage malloc_storage_;
     167    AsanStats stats_;
     168    bool unwinding_;
     169    uptr extra_spill_area_;
     170  };
     171  
     172  // Returns a single instance of registry.
     173  ThreadRegistry &asanThreadRegistry();
     174  
     175  // Must be called under ThreadRegistryLock.
     176  AsanThreadContext *GetThreadContextByTidLocked(u32 tid);
     177  
     178  // Get the current thread. May return 0.
     179  AsanThread *GetCurrentThread();
     180  void SetCurrentThread(AsanThread *t);
     181  u32 GetCurrentTidOrInvalid();
     182  AsanThread *FindThreadByStackAddress(uptr addr);
     183  
     184  // Used to handle fork().
     185  void EnsureMainThreadIDIsCorrect();
     186  } // namespace __asan
     187  
     188  #endif // ASAN_THREAD_H