11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_thread.h -------------------------------------------*- C++ -*-===//
21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//                     The LLVM Compiler Infrastructure
41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source
61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details.
71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker.
111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// ASan-private header for asan_thread.cc.
131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
14799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifndef ASAN_THREAD_H
161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_THREAD_H
171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_allocator.h"
191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h"
20244384d1a8a518c0b1ceaa5809333a91db1104b6Kostya Serebryany#include "asan_fake_stack.h"
211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stats.h"
22e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev#include "sanitizer_common/sanitizer_common.h"
23b134ffa00ce2a4cbf7f48ac029e31c3e6e23ff6bKostya Serebryany#include "sanitizer_common/sanitizer_libc.h"
24def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov#include "sanitizer_common/sanitizer_thread_registry.h"
251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
26c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarnamespace __sanitizer {
27c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstruct DTLS;
28c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}  // namespace __sanitizer
29c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan {
311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
32e0cff0bc20ae51790c8edfbceb817e18ebf5355eKostya Serebryanyconst u32 kInvalidTid = 0xffffff;  // Must fit into 24 bits.
33def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovconst u32 kMaxNumberOfThreads = (1 << 22);  // 4M
34e0cff0bc20ae51790c8edfbceb817e18ebf5355eKostya Serebryany
351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyclass AsanThread;
361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// These objects are created for every thread and are never deleted,
381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// so we can find them by tid even if the thread is long dead.
39def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovclass AsanThreadContext : public ThreadContextBase {
401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany public:
41def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov  explicit AsanThreadContext(int tid)
42799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      : ThreadContextBase(tid), announced(false),
43799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar        destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),
44799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar        thread(nullptr) {}
45def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov  bool announced;
466d95869fa900da9ddd68e15e2aa065854cfa176bKostya Serebryany  u8 destructor_iterations;
476d95869fa900da9ddd68e15e2aa065854cfa176bKostya Serebryany  u32 stack_id;
48def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov  AsanThread *thread;
49f58f998066db0231e521169d2f50af439ceecb49Kostya Serebryany
50259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  void OnCreated(void *arg) override;
51259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  void OnFinished() override;
521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany};
531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
54def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov// AsanThreadContext objects are never freed, so we need many of them.
556d95869fa900da9ddd68e15e2aa065854cfa176bKostya SerebryanyCOMPILER_CHECK(sizeof(AsanThreadContext) <= 256);
56716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany
571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// AsanThread are stored in TSD and destroyed when the thread dies.
581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyclass AsanThread {
591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany public:
6086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  static AsanThread *Create(thread_callback_t start_routine, void *arg,
6186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines                            u32 parent_tid, StackTrace *stack, bool detached);
62def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov  static void TSDDtor(void *tsd);
63a6b52264e1231bfc4ee9a2d9a4f32678c97295f0Kostya Serebryany  void Destroy();
641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
6569eca73ac96688c8bfe1f23ee006af29c7858c40Kostya Serebryany  void Init();  // Should be called from the thread itself.
6686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  thread_return_t ThreadStart(uptr os_id,
6786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines                              atomic_uintptr_t *signal_thread_is_registered);
681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
69c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr stack_top();
70c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr stack_bottom();
71c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr stack_size();
7212d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev  uptr tls_begin() { return tls_begin_; }
7312d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev  uptr tls_end() { return tls_end_; }
74c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  DTLS *dtls() { return dtls_; }
75def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov  u32 tid() { return context_->tid; }
76def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov  AsanThreadContext *context() { return context_; }
77def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov  void set_context(AsanThreadContext *context) { context_ = context; }
781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  struct StackFrameAccess {
806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    uptr offset;
816d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    uptr frame_pc;
826d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    const char *frame_descr;
836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  };
846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  bool GetStackFrameAccessByAddr(uptr addr, StackFrameAccess *access);
851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
86c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  bool AddrIsInStack(uptr addr);
871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void DeleteFakeStack(int tid) {
897a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany    if (!fake_stack_) return;
909433af375c7813486be91d2ac76f5072ee41818dKostya Serebryany    FakeStack *t = fake_stack_;
91799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    fake_stack_ = nullptr;
92799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    SetTLSFakeStack(nullptr);
932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    t->Destroy(tid);
94ac3ae5dc29d3623ada2bcb0db22ee88b0382e3b1Kostya Serebryany  }
95ac3ae5dc29d3623ada2bcb0db22ee88b0382e3b1Kostya Serebryany
96c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void StartSwitchFiber(FakeStack **fake_stack_save, uptr bottom, uptr size);
97c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void FinishSwitchFiber(FakeStack *fake_stack_save);
98c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
99dcf98bf49d68533c7aebadbf6c4467afdd486c99Kostya Serebryany  bool has_fake_stack() {
100c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    return !atomic_load(&stack_switching_, memory_order_relaxed) &&
101c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar           (reinterpret_cast<uptr>(fake_stack_) > 1);
102dcf98bf49d68533c7aebadbf6c4467afdd486c99Kostya Serebryany  }
103dcf98bf49d68533c7aebadbf6c4467afdd486c99Kostya Serebryany
104ac3ae5dc29d3623ada2bcb0db22ee88b0382e3b1Kostya Serebryany  FakeStack *fake_stack() {
105230e52f4e91b53f05ce19dbbf11047f4a0113483Kostya Serebryany    if (!__asan_option_detect_stack_use_after_return)
106799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      return nullptr;
107c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    if (atomic_load(&stack_switching_, memory_order_relaxed))
108c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      return nullptr;
109dcf98bf49d68533c7aebadbf6c4467afdd486c99Kostya Serebryany    if (!has_fake_stack())
110c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany      return AsyncSignalSafeLazyInitFakeStack();
111ac3ae5dc29d3623ada2bcb0db22ee88b0382e3b1Kostya Serebryany    return fake_stack_;
1127a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany  }
1137a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany
11496a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov  // True is this thread is currently unwinding stack (i.e. collecting a stack
11596a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov  // trace). Used to prevent deadlocks on platforms where libc unwinder calls
11696a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov  // malloc internally. See PR17116 for more details.
1172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  bool isUnwinding() const { return unwinding_; }
1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void setUnwinding(bool b) { unwinding_ = b; }
11996a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov
1206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  // True if we are in a deadly signal handler.
1216d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  bool isInDeadlySignal() const { return in_deadly_signal_; }
1226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  void setInDeadlySignal(bool b) { in_deadly_signal_ = b; }
1236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  AsanStats &stats() { return stats_; }
1261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany private:
1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // NOTE: There is no AsanThread constructor. It is allocated
1292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // via mmap() and *must* be valid in zero-initialized state.
13012d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev  void SetThreadStackAndTls();
13112d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev  void ClearShadowForThreadStackAndTLS();
132c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany  FakeStack *AsyncSignalSafeLazyInitFakeStack();
133c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany
134c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  struct StackBounds {
135c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    uptr bottom;
136c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    uptr top;
137c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  };
138c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  StackBounds GetStackBounds() const;
139c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
140def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov  AsanThreadContext *context_;
141600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov  thread_callback_t start_routine_;
1421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  void *arg_;
143c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr stack_top_;
1452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr stack_bottom_;
146c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // these variables are used when the thread is about to switch stack
147c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr next_stack_top_;
148c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr next_stack_bottom_;
149c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // true if switching is in progress
150c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  atomic_uint8_t stack_switching_;
151c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
15212d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev  uptr tls_begin_;
15312d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev  uptr tls_end_;
154c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  DTLS *dtls_;
1551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1567a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany  FakeStack *fake_stack_;
1571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  AsanThreadLocalMallocStorage malloc_storage_;
1581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  AsanStats stats_;
1592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  bool unwinding_;
1606d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  bool in_deadly_signal_;
16196a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov};
16296a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov
16396a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov// ScopedUnwinding is a scope for stacktracing member of a context
16496a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanovclass ScopedUnwinding {
16596a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov public:
16696a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov  explicit ScopedUnwinding(AsanThread *t) : thread(t) {
16796a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov    t->setUnwinding(true);
16896a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov  }
16996a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov  ~ScopedUnwinding() { thread->setUnwinding(false); }
17096a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov
17196a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov private:
17296a575f05b2a45774170a118ea69ddae3659b645Evgeniy Stepanov  AsanThread *thread;
1731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany};
1741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1756d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// ScopedDeadlySignal is a scope for handling deadly signals.
1766d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesclass ScopedDeadlySignal {
1776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines public:
1786d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  explicit ScopedDeadlySignal(AsanThread *t) : thread(t) {
1796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    if (thread) thread->setInDeadlySignal(true);
1806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
1816d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  ~ScopedDeadlySignal() {
1826d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    if (thread) thread->setInDeadlySignal(false);
1836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
1846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
1856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines private:
1866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  AsanThread *thread;
1876d1862363c88c183b0ed7740fca876342cf0474bStephen Hines};
1886d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
189def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov// Returns a single instance of registry.
190def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey SamsonovThreadRegistry &asanThreadRegistry();
191def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
192def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov// Must be called under ThreadRegistryLock.
193def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey SamsonovAsanThreadContext *GetThreadContextByTidLocked(u32 tid);
194def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
19589c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov// Get the current thread. May return 0.
19689c1384464848c1ad041becf8b97936fa10de21bAlexey SamsonovAsanThread *GetCurrentThread();
19789c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonovvoid SetCurrentThread(AsanThread *t);
19889c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonovu32 GetCurrentTidOrInvalid();
199def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey SamsonovAsanThread *FindThreadByStackAddress(uptr addr);
20089c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov
201c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev// Used to handle fork().
202c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveevvoid EnsureMainThreadIDIsCorrect();
203799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar} // namespace __asan
2041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
205799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif // ASAN_THREAD_H
206