blob: 1bce25c28c409b46c7b3eaf29542032c693f5844 [file] [log] [blame]
Kostya Serebryany1e172b42011-11-30 01:07:02 +00001//===-- asan_thread.h -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of AddressSanitizer, an address sanity checker.
11//
12// ASan-private header for asan_thread.cc.
13//===----------------------------------------------------------------------===//
14#ifndef ASAN_THREAD_H
15#define ASAN_THREAD_H
16
17#include "asan_allocator.h"
18#include "asan_internal.h"
Kostya Serebryany244384d2013-04-11 11:39:19 +000019#include "asan_fake_stack.h"
Kostya Serebryany1e172b42011-11-30 01:07:02 +000020#include "asan_stats.h"
Sergey Matveeve86e35f2013-10-14 12:01:05 +000021#include "sanitizer_common/sanitizer_common.h"
Kostya Serebryanyb134ffa2012-07-17 07:20:13 +000022#include "sanitizer_common/sanitizer_libc.h"
Alexey Samsonovdef1be92013-03-21 11:23:41 +000023#include "sanitizer_common/sanitizer_thread_registry.h"
Kostya Serebryany1e172b42011-11-30 01:07:02 +000024
25namespace __asan {
26
Kostya Serebryanye0cff0b2012-06-06 15:06:58 +000027const u32 kInvalidTid = 0xffffff; // Must fit into 24 bits.
Alexey Samsonovdef1be92013-03-21 11:23:41 +000028const u32 kMaxNumberOfThreads = (1 << 22); // 4M
Kostya Serebryanye0cff0b2012-06-06 15:06:58 +000029
Kostya Serebryany1e172b42011-11-30 01:07:02 +000030class AsanThread;
31
32// These objects are created for every thread and are never deleted,
33// so we can find them by tid even if the thread is long dead.
Alexey Samsonovdef1be92013-03-21 11:23:41 +000034class AsanThreadContext : public ThreadContextBase {
Kostya Serebryany1e172b42011-11-30 01:07:02 +000035 public:
Alexey Samsonovdef1be92013-03-21 11:23:41 +000036 explicit AsanThreadContext(int tid)
37 : ThreadContextBase(tid),
38 announced(false),
Sergey Matveeve86e35f2013-10-14 12:01:05 +000039 destructor_iterations(kPthreadDestructorIterations),
Kostya Serebryany6d958692013-10-18 14:50:44 +000040 stack_id(0),
Alexey Samsonovdef1be92013-03-21 11:23:41 +000041 thread(0) {
Kostya Serebryany1e172b42011-11-30 01:07:02 +000042 }
Alexey Samsonovdef1be92013-03-21 11:23:41 +000043 bool announced;
Kostya Serebryany6d958692013-10-18 14:50:44 +000044 u8 destructor_iterations;
45 u32 stack_id;
Alexey Samsonovdef1be92013-03-21 11:23:41 +000046 AsanThread *thread;
Kostya Serebryanyf58f9982012-02-07 00:27:15 +000047
Alexey Samsonovdef1be92013-03-21 11:23:41 +000048 void OnCreated(void *arg);
49 void OnFinished();
Kostya Serebryany1e172b42011-11-30 01:07:02 +000050};
51
Alexey Samsonovdef1be92013-03-21 11:23:41 +000052// AsanThreadContext objects are never freed, so we need many of them.
Kostya Serebryany6d958692013-10-18 14:50:44 +000053COMPILER_CHECK(sizeof(AsanThreadContext) <= 256);
Kostya Serebryany716e2f22012-12-07 15:15:01 +000054
Kostya Serebryany1e172b42011-11-30 01:07:02 +000055// AsanThread are stored in TSD and destroyed when the thread dies.
56class AsanThread {
57 public:
Alexey Samsonovdef1be92013-03-21 11:23:41 +000058 static AsanThread *Create(thread_callback_t start_routine, void *arg);
59 static void TSDDtor(void *tsd);
Kostya Serebryanya6b52262012-01-06 19:44:11 +000060 void Destroy();
Kostya Serebryany1e172b42011-11-30 01:07:02 +000061
Kostya Serebryany69eca732011-12-16 19:13:35 +000062 void Init(); // Should be called from the thread itself.
Alexey Samsonovdef1be92013-03-21 11:23:41 +000063 thread_return_t ThreadStart(uptr os_id);
Kostya Serebryany1e172b42011-11-30 01:07:02 +000064
Kostya Serebryany3f4c3872012-05-31 14:35:53 +000065 uptr stack_top() { return stack_top_; }
66 uptr stack_bottom() { return stack_bottom_; }
Kostya Serebryany621770a2013-09-19 14:59:52 +000067 uptr stack_size() { return stack_size_; }
Sergey Matveev12d01ba2013-05-29 13:09:44 +000068 uptr tls_begin() { return tls_begin_; }
69 uptr tls_end() { return tls_end_; }
Alexey Samsonovdef1be92013-03-21 11:23:41 +000070 u32 tid() { return context_->tid; }
71 AsanThreadContext *context() { return context_; }
72 void set_context(AsanThreadContext *context) { context_ = context; }
Kostya Serebryany1e172b42011-11-30 01:07:02 +000073
Kostya Serebryany50f3daa2013-03-22 10:36:24 +000074 const char *GetFrameNameByAddr(uptr addr, uptr *offset, uptr *frame_pc);
Kostya Serebryany1e172b42011-11-30 01:07:02 +000075
Kostya Serebryany3f4c3872012-05-31 14:35:53 +000076 bool AddrIsInStack(uptr addr) {
Kostya Serebryany1e172b42011-11-30 01:07:02 +000077 return addr >= stack_bottom_ && addr < stack_top_;
78 }
79
Stephen Hines2d1fdb22014-05-28 23:58:16 -070080 void DeleteFakeStack(int tid) {
Kostya Serebryany7a0bba42013-06-26 12:16:05 +000081 if (!fake_stack_) return;
Kostya Serebryany9433af32013-09-13 06:32:26 +000082 FakeStack *t = fake_stack_;
83 fake_stack_ = 0;
84 SetTLSFakeStack(0);
Stephen Hines2d1fdb22014-05-28 23:58:16 -070085 t->Destroy(tid);
Kostya Serebryany7a0bba42013-06-26 12:16:05 +000086 }
Kostya Serebryanyac3ae5d2013-09-12 07:11:58 +000087
Kostya Serebryanydcf98bf2013-09-12 08:43:44 +000088 bool has_fake_stack() {
89 return (reinterpret_cast<uptr>(fake_stack_) > 1);
90 }
91
Kostya Serebryanyac3ae5d2013-09-12 07:11:58 +000092 FakeStack *fake_stack() {
Kostya Serebryany230e52f2013-09-18 10:35:12 +000093 if (!__asan_option_detect_stack_use_after_return)
94 return 0;
Kostya Serebryanydcf98bf2013-09-12 08:43:44 +000095 if (!has_fake_stack())
Kostya Serebryanyc98fc1f2013-09-12 08:34:50 +000096 return AsyncSignalSafeLazyInitFakeStack();
Kostya Serebryanyac3ae5d2013-09-12 07:11:58 +000097 return fake_stack_;
98 }
Kostya Serebryany7a0bba42013-06-26 12:16:05 +000099
Evgeniy Stepanov96a575f2013-09-12 08:16:28 +0000100 // True is this thread is currently unwinding stack (i.e. collecting a stack
101 // trace). Used to prevent deadlocks on platforms where libc unwinder calls
102 // malloc internally. See PR17116 for more details.
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700103 bool isUnwinding() const { return unwinding_; }
104 void setUnwinding(bool b) { unwinding_ = b; }
Evgeniy Stepanov96a575f2013-09-12 08:16:28 +0000105
Kostya Serebryany1e172b42011-11-30 01:07:02 +0000106 AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
107 AsanStats &stats() { return stats_; }
108
Kostya Serebryany1e172b42011-11-30 01:07:02 +0000109 private:
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700110 // NOTE: There is no AsanThread constructor. It is allocated
111 // via mmap() and *must* be valid in zero-initialized state.
Sergey Matveev12d01ba2013-05-29 13:09:44 +0000112 void SetThreadStackAndTls();
113 void ClearShadowForThreadStackAndTLS();
Kostya Serebryanyc98fc1f2013-09-12 08:34:50 +0000114 FakeStack *AsyncSignalSafeLazyInitFakeStack();
115
Alexey Samsonovdef1be92013-03-21 11:23:41 +0000116 AsanThreadContext *context_;
Timur Iskhodzhanov600972e2012-02-24 15:28:43 +0000117 thread_callback_t start_routine_;
Kostya Serebryany1e172b42011-11-30 01:07:02 +0000118 void *arg_;
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700119 uptr stack_top_;
120 uptr stack_bottom_;
Kostya Serebryany621770a2013-09-19 14:59:52 +0000121 // stack_size_ == stack_top_ - stack_bottom_;
122 // It needs to be set in a async-signal-safe manner.
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700123 uptr stack_size_;
Sergey Matveev12d01ba2013-05-29 13:09:44 +0000124 uptr tls_begin_;
125 uptr tls_end_;
Kostya Serebryany1e172b42011-11-30 01:07:02 +0000126
Kostya Serebryany7a0bba42013-06-26 12:16:05 +0000127 FakeStack *fake_stack_;
Kostya Serebryany1e172b42011-11-30 01:07:02 +0000128 AsanThreadLocalMallocStorage malloc_storage_;
129 AsanStats stats_;
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700130 bool unwinding_;
Evgeniy Stepanov96a575f2013-09-12 08:16:28 +0000131};
132
133// ScopedUnwinding is a scope for stacktracing member of a context
134class ScopedUnwinding {
135 public:
136 explicit ScopedUnwinding(AsanThread *t) : thread(t) {
137 t->setUnwinding(true);
138 }
139 ~ScopedUnwinding() { thread->setUnwinding(false); }
140
141 private:
142 AsanThread *thread;
Kostya Serebryany1e172b42011-11-30 01:07:02 +0000143};
144
Alexey Samsonovdef1be92013-03-21 11:23:41 +0000145struct CreateThreadContextArgs {
146 AsanThread *thread;
147 StackTrace *stack;
148};
149
150// Returns a single instance of registry.
151ThreadRegistry &asanThreadRegistry();
152
153// Must be called under ThreadRegistryLock.
154AsanThreadContext *GetThreadContextByTidLocked(u32 tid);
155
Alexey Samsonov89c13842013-03-20 09:23:28 +0000156// Get the current thread. May return 0.
157AsanThread *GetCurrentThread();
158void SetCurrentThread(AsanThread *t);
159u32 GetCurrentTidOrInvalid();
Alexey Samsonovdef1be92013-03-21 11:23:41 +0000160AsanThread *FindThreadByStackAddress(uptr addr);
Alexey Samsonov89c13842013-03-20 09:23:28 +0000161
Sergey Matveevc6ac98d2013-07-08 12:57:24 +0000162// Used to handle fork().
163void EnsureMainThreadIDIsCorrect();
Kostya Serebryany1e172b42011-11-30 01:07:02 +0000164} // namespace __asan
165
166#endif // ASAN_THREAD_H