blob: 11771ecd09f099d8fd89c13e59df97a97fd468eb [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_stack.h"
21#include "asan_stats.h"
Sergey Matveeve86e35f2013-10-14 12:01:05 +000022#include "sanitizer_common/sanitizer_common.h"
Kostya Serebryanyb134ffa2012-07-17 07:20:13 +000023#include "sanitizer_common/sanitizer_libc.h"
Alexey Samsonovdef1be92013-03-21 11:23:41 +000024#include "sanitizer_common/sanitizer_thread_registry.h"
Kostya Serebryany1e172b42011-11-30 01:07:02 +000025
26namespace __asan {
27
Kostya Serebryanye0cff0b2012-06-06 15:06:58 +000028const u32 kInvalidTid = 0xffffff; // Must fit into 24 bits.
Alexey Samsonovdef1be92013-03-21 11:23:41 +000029const u32 kMaxNumberOfThreads = (1 << 22); // 4M
Kostya Serebryanye0cff0b2012-06-06 15:06:58 +000030
Kostya Serebryany1e172b42011-11-30 01:07:02 +000031class 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.
Alexey Samsonovdef1be92013-03-21 11:23:41 +000035class AsanThreadContext : public ThreadContextBase {
Kostya Serebryany1e172b42011-11-30 01:07:02 +000036 public:
Alexey Samsonovdef1be92013-03-21 11:23:41 +000037 explicit AsanThreadContext(int tid)
38 : ThreadContextBase(tid),
39 announced(false),
Sergey Matveeve86e35f2013-10-14 12:01:05 +000040 destructor_iterations(kPthreadDestructorIterations),
Kostya Serebryany6d958692013-10-18 14:50:44 +000041 stack_id(0),
Alexey Samsonovdef1be92013-03-21 11:23:41 +000042 thread(0) {
Kostya Serebryany1e172b42011-11-30 01:07:02 +000043 }
Alexey Samsonovdef1be92013-03-21 11:23:41 +000044 bool announced;
Kostya Serebryany6d958692013-10-18 14:50:44 +000045 u8 destructor_iterations;
46 u32 stack_id;
Alexey Samsonovdef1be92013-03-21 11:23:41 +000047 AsanThread *thread;
Kostya Serebryanyf58f9982012-02-07 00:27:15 +000048
Alexey Samsonovdef1be92013-03-21 11:23:41 +000049 void OnCreated(void *arg);
50 void OnFinished();
Kostya Serebryany1e172b42011-11-30 01:07:02 +000051};
52
Alexey Samsonovdef1be92013-03-21 11:23:41 +000053// AsanThreadContext objects are never freed, so we need many of them.
Kostya Serebryany6d958692013-10-18 14:50:44 +000054COMPILER_CHECK(sizeof(AsanThreadContext) <= 256);
Kostya Serebryany716e2f22012-12-07 15:15:01 +000055
Kostya Serebryany1e172b42011-11-30 01:07:02 +000056// AsanThread are stored in TSD and destroyed when the thread dies.
57class AsanThread {
58 public:
Alexey Samsonovdef1be92013-03-21 11:23:41 +000059 static AsanThread *Create(thread_callback_t start_routine, void *arg);
60 static void TSDDtor(void *tsd);
Kostya Serebryanya6b52262012-01-06 19:44:11 +000061 void Destroy();
Kostya Serebryany1e172b42011-11-30 01:07:02 +000062
Kostya Serebryany69eca732011-12-16 19:13:35 +000063 void Init(); // Should be called from the thread itself.
Alexey Samsonovdef1be92013-03-21 11:23:41 +000064 thread_return_t ThreadStart(uptr os_id);
Kostya Serebryany1e172b42011-11-30 01:07:02 +000065
Kostya Serebryany3f4c3872012-05-31 14:35:53 +000066 uptr stack_top() { return stack_top_; }
67 uptr stack_bottom() { return stack_bottom_; }
Kostya Serebryany621770a2013-09-19 14:59:52 +000068 uptr stack_size() { return stack_size_; }
Sergey Matveev12d01ba2013-05-29 13:09:44 +000069 uptr tls_begin() { return tls_begin_; }
70 uptr tls_end() { return tls_end_; }
Alexey Samsonovdef1be92013-03-21 11:23:41 +000071 u32 tid() { return context_->tid; }
72 AsanThreadContext *context() { return context_; }
73 void set_context(AsanThreadContext *context) { context_ = context; }
Kostya Serebryany1e172b42011-11-30 01:07:02 +000074
Kostya Serebryany50f3daa2013-03-22 10:36:24 +000075 const char *GetFrameNameByAddr(uptr addr, uptr *offset, uptr *frame_pc);
Kostya Serebryany1e172b42011-11-30 01:07:02 +000076
Kostya Serebryany3f4c3872012-05-31 14:35:53 +000077 bool AddrIsInStack(uptr addr) {
Kostya Serebryany1e172b42011-11-30 01:07:02 +000078 return addr >= stack_bottom_ && addr < stack_top_;
79 }
80
Kostya Serebryany7a0bba42013-06-26 12:16:05 +000081 void DeleteFakeStack() {
82 if (!fake_stack_) return;
Kostya Serebryany9433af32013-09-13 06:32:26 +000083 FakeStack *t = fake_stack_;
84 fake_stack_ = 0;
85 SetTLSFakeStack(0);
86 t->Destroy();
Kostya Serebryany7a0bba42013-06-26 12:16:05 +000087 }
Kostya Serebryanyac3ae5d2013-09-12 07:11:58 +000088
Kostya Serebryanydcf98bf2013-09-12 08:43:44 +000089 bool has_fake_stack() {
90 return (reinterpret_cast<uptr>(fake_stack_) > 1);
91 }
92
Kostya Serebryanyac3ae5d2013-09-12 07:11:58 +000093 FakeStack *fake_stack() {
Kostya Serebryany230e52f2013-09-18 10:35:12 +000094 if (!__asan_option_detect_stack_use_after_return)
95 return 0;
Kostya Serebryanydcf98bf2013-09-12 08:43:44 +000096 if (!has_fake_stack())
Kostya Serebryanyc98fc1f2013-09-12 08:34:50 +000097 return AsyncSignalSafeLazyInitFakeStack();
Kostya Serebryanyac3ae5d2013-09-12 07:11:58 +000098 return fake_stack_;
99 }
Kostya Serebryany7a0bba42013-06-26 12:16:05 +0000100
Evgeniy Stepanov96a575f2013-09-12 08:16:28 +0000101 // True is this thread is currently unwinding stack (i.e. collecting a stack
102 // trace). Used to prevent deadlocks on platforms where libc unwinder calls
103 // malloc internally. See PR17116 for more details.
104 bool isUnwinding() const { return unwinding; }
105 void setUnwinding(bool b) { unwinding = b; }
106
Kostya Serebryany1e172b42011-11-30 01:07:02 +0000107 AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
108 AsanStats &stats() { return stats_; }
109
Kostya Serebryany1e172b42011-11-30 01:07:02 +0000110 private:
Evgeniy Stepanov96a575f2013-09-12 08:16:28 +0000111 AsanThread() : unwinding(false) {}
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_;
Kostya Serebryany3f4c3872012-05-31 14:35:53 +0000119 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.
123 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_;
Evgeniy Stepanov96a575f2013-09-12 08:16:28 +0000130 bool unwinding;
131};
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