1238901Sandrew//===-- asan_thread.cc ----------------------------------------------------===//
2229109Sed//
3229109Sed//                     The LLVM Compiler Infrastructure
4229109Sed//
5229109Sed// This file is distributed under the University of Illinois Open Source
6229109Sed// License. See LICENSE.TXT for details.
7229109Sed//
8229109Sed//===----------------------------------------------------------------------===//
9229109Sed//
10229109Sed// This file is a part of AddressSanitizer, an address sanity checker.
11229109Sed//
12229109Sed// Thread-related code.
13229109Sed//===----------------------------------------------------------------------===//
14229109Sed#include "asan_allocator.h"
15229109Sed#include "asan_interceptors.h"
16251034Sed#include "asan_poisoning.h"
17238901Sandrew#include "asan_stack.h"
18229109Sed#include "asan_thread.h"
19229109Sed#include "asan_mapping.h"
20238901Sandrew#include "sanitizer_common/sanitizer_common.h"
21251034Sed#include "sanitizer_common/sanitizer_placement_new.h"
22274201Sdim#include "sanitizer_common/sanitizer_stackdepot.h"
23276789Sdim#include "sanitizer_common/sanitizer_tls_get_addr.h"
24251034Sed#include "lsan/lsan_common.h"
25229109Sed
26229109Sednamespace __asan {
27229109Sed
28251034Sed// AsanThreadContext implementation.
29229109Sed
30276789Sdimstruct CreateThreadContextArgs {
31276789Sdim  AsanThread *thread;
32276789Sdim  StackTrace *stack;
33276789Sdim};
34276789Sdim
35251034Sedvoid AsanThreadContext::OnCreated(void *arg) {
36251034Sed  CreateThreadContextArgs *args = static_cast<CreateThreadContextArgs*>(arg);
37274201Sdim  if (args->stack)
38276789Sdim    stack_id = StackDepotPut(*args->stack);
39251034Sed  thread = args->thread;
40251034Sed  thread->set_context(this);
41251034Sed}
42251034Sed
43251034Sedvoid AsanThreadContext::OnFinished() {
44251034Sed  // Drop the link to the AsanThread object.
45296417Sdim  thread = nullptr;
46251034Sed}
47251034Sed
48274201Sdim// MIPS requires aligned address
49274201Sdimstatic ALIGNED(16) char thread_registry_placeholder[sizeof(ThreadRegistry)];
50251034Sedstatic ThreadRegistry *asan_thread_registry;
51251034Sed
52274201Sdimstatic BlockingMutex mu_for_thread_context(LINKER_INITIALIZED);
53274201Sdimstatic LowLevelAllocator allocator_for_thread_context;
54274201Sdim
55251034Sedstatic ThreadContextBase *GetAsanThreadContext(u32 tid) {
56274201Sdim  BlockingMutexLock lock(&mu_for_thread_context);
57274201Sdim  return new(allocator_for_thread_context) AsanThreadContext(tid);
58251034Sed}
59251034Sed
60251034SedThreadRegistry &asanThreadRegistry() {
61251034Sed  static bool initialized;
62251034Sed  // Don't worry about thread_safety - this should be called when there is
63251034Sed  // a single thread.
64251034Sed  if (!initialized) {
65251034Sed    // Never reuse ASan threads: we store pointer to AsanThreadContext
66251034Sed    // in TSD and can't reliably tell when no more TSD destructors will
67251034Sed    // be called. It would be wrong to reuse AsanThreadContext for another
68251034Sed    // thread before all TSD destructors will be called for it.
69251034Sed    asan_thread_registry = new(thread_registry_placeholder) ThreadRegistry(
70251034Sed        GetAsanThreadContext, kMaxNumberOfThreads, kMaxNumberOfThreads);
71251034Sed    initialized = true;
72251034Sed  }
73251034Sed  return *asan_thread_registry;
74251034Sed}
75251034Sed
76251034SedAsanThreadContext *GetThreadContextByTidLocked(u32 tid) {
77251034Sed  return static_cast<AsanThreadContext *>(
78251034Sed      asanThreadRegistry().GetThreadLocked(tid));
79251034Sed}
80251034Sed
81251034Sed// AsanThread implementation.
82251034Sed
83276789SdimAsanThread *AsanThread::Create(thread_callback_t start_routine, void *arg,
84276789Sdim                               u32 parent_tid, StackTrace *stack,
85276789Sdim                               bool detached) {
86245614Sandrew  uptr PageSize = GetPageSizeCached();
87245614Sandrew  uptr size = RoundUpTo(sizeof(AsanThread), PageSize);
88276789Sdim  AsanThread *thread = (AsanThread*)MmapOrDie(size, __func__);
89238901Sandrew  thread->start_routine_ = start_routine;
90238901Sandrew  thread->arg_ = arg;
91276789Sdim  CreateThreadContextArgs args = { thread, stack };
92276789Sdim  asanThreadRegistry().CreateThread(*reinterpret_cast<uptr *>(thread), detached,
93276789Sdim                                    parent_tid, &args);
94238901Sandrew
95238901Sandrew  return thread;
96229109Sed}
97229109Sed
98251034Sedvoid AsanThread::TSDDtor(void *tsd) {
99251034Sed  AsanThreadContext *context = (AsanThreadContext*)tsd;
100276789Sdim  VReport(1, "T%d TSDDtor\n", context->tid);
101251034Sed  if (context->thread)
102251034Sed    context->thread->Destroy();
103238901Sandrew}
104238901Sandrew
105238901Sandrewvoid AsanThread::Destroy() {
106276789Sdim  int tid = this->tid();
107276789Sdim  VReport(1, "T%d exited\n", tid);
108238901Sandrew
109274201Sdim  malloc_storage().CommitBack();
110276789Sdim  if (common_flags()->use_sigaltstack) UnsetAlternateSignalStack();
111276789Sdim  asanThreadRegistry().FinishThread(tid);
112274201Sdim  FlushToDeadThreadStats(&stats_);
113229109Sed  // We also clear the shadow on thread destruction because
114229109Sed  // some code may still be executing in later TSD destructors
115229109Sed  // and we don't want it to have any poisoned stack.
116274201Sdim  ClearShadowForThreadStackAndTLS();
117276789Sdim  DeleteFakeStack(tid);
118245614Sandrew  uptr size = RoundUpTo(sizeof(AsanThread), GetPageSizeCached());
119238901Sandrew  UnmapOrDie(this, size);
120276789Sdim  DTLS_Destroy();
121229109Sed}
122229109Sed
123274201Sdim// We want to create the FakeStack lazyly on the first use, but not eralier
124274201Sdim// than the stack size is known and the procedure has to be async-signal safe.
125274201SdimFakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
126274201Sdim  uptr stack_size = this->stack_size();
127274201Sdim  if (stack_size == 0)  // stack_size is not yet available, don't use FakeStack.
128296417Sdim    return nullptr;
129274201Sdim  uptr old_val = 0;
130274201Sdim  // fake_stack_ has 3 states:
131274201Sdim  // 0   -- not initialized
132274201Sdim  // 1   -- being initialized
133274201Sdim  // ptr -- initialized
134274201Sdim  // This CAS checks if the state was 0 and if so changes it to state 1,
135276789Sdim  // if that was successful, it initializes the pointer.
136274201Sdim  if (atomic_compare_exchange_strong(
137274201Sdim      reinterpret_cast<atomic_uintptr_t *>(&fake_stack_), &old_val, 1UL,
138274201Sdim      memory_order_relaxed)) {
139274201Sdim    uptr stack_size_log = Log2(RoundUpToPowerOfTwo(stack_size));
140276789Sdim    CHECK_LE(flags()->min_uar_stack_size_log, flags()->max_uar_stack_size_log);
141276789Sdim    stack_size_log =
142276789Sdim        Min(stack_size_log, static_cast<uptr>(flags()->max_uar_stack_size_log));
143276789Sdim    stack_size_log =
144276789Sdim        Max(stack_size_log, static_cast<uptr>(flags()->min_uar_stack_size_log));
145274201Sdim    fake_stack_ = FakeStack::Create(stack_size_log);
146274201Sdim    SetTLSFakeStack(fake_stack_);
147274201Sdim    return fake_stack_;
148274201Sdim  }
149296417Sdim  return nullptr;
150274201Sdim}
151274201Sdim
152229109Sedvoid AsanThread::Init() {
153296417Sdim  fake_stack_ = nullptr;  // Will be initialized lazily if needed.
154276789Sdim  CHECK_EQ(this->stack_size(), 0U);
155274201Sdim  SetThreadStackAndTls();
156276789Sdim  CHECK_GT(this->stack_size(), 0U);
157229109Sed  CHECK(AddrIsInMem(stack_bottom_));
158245614Sandrew  CHECK(AddrIsInMem(stack_top_ - 1));
159274201Sdim  ClearShadowForThreadStackAndTLS();
160276789Sdim  int local = 0;
161276789Sdim  VReport(1, "T%d: stack [%p,%p) size 0x%zx; local=%p\n", tid(),
162276789Sdim          (void *)stack_bottom_, (void *)stack_top_, stack_top_ - stack_bottom_,
163276789Sdim          &local);
164229109Sed}
165229109Sed
166276789Sdimthread_return_t AsanThread::ThreadStart(
167276789Sdim    uptr os_id, atomic_uintptr_t *signal_thread_is_registered) {
168229109Sed  Init();
169296417Sdim  asanThreadRegistry().StartThread(tid(), os_id, nullptr);
170276789Sdim  if (signal_thread_is_registered)
171276789Sdim    atomic_store(signal_thread_is_registered, 1, memory_order_release);
172229109Sed
173276789Sdim  if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
174276789Sdim
175229109Sed  if (!start_routine_) {
176238901Sandrew    // start_routine_ == 0 if we're on the main thread or on one of the
177229109Sed    // OS X libdispatch worker threads. But nobody is supposed to call
178229109Sed    // ThreadStart() for the worker threads.
179251034Sed    CHECK_EQ(tid(), 0);
180229109Sed    return 0;
181229109Sed  }
182229109Sed
183238901Sandrew  thread_return_t res = start_routine_(arg_);
184229109Sed
185274201Sdim  // On POSIX systems we defer this to the TSD destructor. LSan will consider
186274201Sdim  // the thread's memory as non-live from the moment we call Destroy(), even
187274201Sdim  // though that memory might contain pointers to heap objects which will be
188274201Sdim  // cleaned up by a user-defined TSD destructor. Thus, calling Destroy() before
189274201Sdim  // the TSD destructors have run might cause false positives in LSan.
190274201Sdim  if (!SANITIZER_POSIX)
191274201Sdim    this->Destroy();
192229109Sed
193229109Sed  return res;
194229109Sed}
195229109Sed
196274201Sdimvoid AsanThread::SetThreadStackAndTls() {
197274201Sdim  uptr tls_size = 0;
198274201Sdim  GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size_, &tls_begin_,
199274201Sdim                       &tls_size);
200274201Sdim  stack_top_ = stack_bottom_ + stack_size_;
201274201Sdim  tls_end_ = tls_begin_ + tls_size;
202274201Sdim
203238901Sandrew  int local;
204238901Sandrew  CHECK(AddrIsInStack((uptr)&local));
205238901Sandrew}
206238901Sandrew
207274201Sdimvoid AsanThread::ClearShadowForThreadStackAndTLS() {
208238901Sandrew  PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0);
209274201Sdim  if (tls_begin_ != tls_end_)
210274201Sdim    PoisonShadow(tls_begin_, tls_end_ - tls_begin_, 0);
211238901Sandrew}
212238901Sandrew
213276789Sdimbool AsanThread::GetStackFrameAccessByAddr(uptr addr,
214276789Sdim                                           StackFrameAccess *access) {
215238901Sandrew  uptr bottom = 0;
216229109Sed  if (AddrIsInStack(addr)) {
217229109Sed    bottom = stack_bottom();
218274201Sdim  } else if (has_fake_stack()) {
219274201Sdim    bottom = fake_stack()->AddrIsInFakeStack(addr);
220229109Sed    CHECK(bottom);
221276789Sdim    access->offset = addr - bottom;
222276789Sdim    access->frame_pc = ((uptr*)bottom)[2];
223276789Sdim    access->frame_descr = (const char *)((uptr*)bottom)[1];
224276789Sdim    return true;
225229109Sed  }
226245614Sandrew  uptr aligned_addr = addr & ~(SANITIZER_WORDSIZE/8 - 1);  // align addr.
227238901Sandrew  u8 *shadow_ptr = (u8*)MemToShadow(aligned_addr);
228238901Sandrew  u8 *shadow_bottom = (u8*)MemToShadow(bottom);
229238901Sandrew
230238901Sandrew  while (shadow_ptr >= shadow_bottom &&
231245614Sandrew         *shadow_ptr != kAsanStackLeftRedzoneMagic) {
232238901Sandrew    shadow_ptr--;
233229109Sed  }
234229109Sed
235238901Sandrew  while (shadow_ptr >= shadow_bottom &&
236245614Sandrew         *shadow_ptr == kAsanStackLeftRedzoneMagic) {
237238901Sandrew    shadow_ptr--;
238238901Sandrew  }
239229109Sed
240238901Sandrew  if (shadow_ptr < shadow_bottom) {
241276789Sdim    return false;
242229109Sed  }
243229109Sed
244238901Sandrew  uptr* ptr = (uptr*)SHADOW_TO_MEM((uptr)(shadow_ptr + 1));
245245614Sandrew  CHECK(ptr[0] == kCurrentStackFrameMagic);
246276789Sdim  access->offset = addr - (uptr)ptr;
247276789Sdim  access->frame_pc = ptr[2];
248276789Sdim  access->frame_descr = (const char*)ptr[1];
249276789Sdim  return true;
250229109Sed}
251229109Sed
252251034Sedstatic bool ThreadStackContainsAddress(ThreadContextBase *tctx_base,
253251034Sed                                       void *addr) {
254251034Sed  AsanThreadContext *tctx = static_cast<AsanThreadContext*>(tctx_base);
255251034Sed  AsanThread *t = tctx->thread;
256274201Sdim  if (!t) return false;
257274201Sdim  if (t->AddrIsInStack((uptr)addr)) return true;
258274201Sdim  if (t->has_fake_stack() && t->fake_stack()->AddrIsInFakeStack((uptr)addr))
259274201Sdim    return true;
260274201Sdim  return false;
261251034Sed}
262251034Sed
263251034SedAsanThread *GetCurrentThread() {
264274201Sdim  AsanThreadContext *context =
265274201Sdim      reinterpret_cast<AsanThreadContext *>(AsanTSDGet());
266251034Sed  if (!context) {
267251034Sed    if (SANITIZER_ANDROID) {
268251034Sed      // On Android, libc constructor is called _after_ asan_init, and cleans up
269251034Sed      // TSD. Try to figure out if this is still the main thread by the stack
270251034Sed      // address. We are not entirely sure that we have correct main thread
271251034Sed      // limits, so only do this magic on Android, and only if the found thread
272251034Sed      // is the main thread.
273251034Sed      AsanThreadContext *tctx = GetThreadContextByTidLocked(0);
274251034Sed      if (ThreadStackContainsAddress(tctx, &context)) {
275251034Sed        SetCurrentThread(tctx->thread);
276251034Sed        return tctx->thread;
277251034Sed      }
278251034Sed    }
279296417Sdim    return nullptr;
280251034Sed  }
281251034Sed  return context->thread;
282251034Sed}
283251034Sed
284251034Sedvoid SetCurrentThread(AsanThread *t) {
285251034Sed  CHECK(t->context());
286276789Sdim  VReport(2, "SetCurrentThread: %p for thread %p\n", t->context(),
287276789Sdim          (void *)GetThreadSelf());
288251034Sed  // Make sure we do not reset the current AsanThread.
289251034Sed  CHECK_EQ(0, AsanTSDGet());
290251034Sed  AsanTSDSet(t->context());
291251034Sed  CHECK_EQ(t->context(), AsanTSDGet());
292251034Sed}
293251034Sed
294251034Sedu32 GetCurrentTidOrInvalid() {
295251034Sed  AsanThread *t = GetCurrentThread();
296251034Sed  return t ? t->tid() : kInvalidTid;
297251034Sed}
298251034Sed
299251034SedAsanThread *FindThreadByStackAddress(uptr addr) {
300251034Sed  asanThreadRegistry().CheckLocked();
301251034Sed  AsanThreadContext *tctx = static_cast<AsanThreadContext *>(
302251034Sed      asanThreadRegistry().FindThreadContextLocked(ThreadStackContainsAddress,
303251034Sed                                                   (void *)addr));
304296417Sdim  return tctx ? tctx->thread : nullptr;
305251034Sed}
306274201Sdim
307274201Sdimvoid EnsureMainThreadIDIsCorrect() {
308274201Sdim  AsanThreadContext *context =
309274201Sdim      reinterpret_cast<AsanThreadContext *>(AsanTSDGet());
310274201Sdim  if (context && (context->tid == 0))
311274201Sdim    context->os_id = GetTid();
312274201Sdim}
313274201Sdim
314274201Sdim__asan::AsanThread *GetAsanThreadByOsIDLocked(uptr os_id) {
315274201Sdim  __asan::AsanThreadContext *context = static_cast<__asan::AsanThreadContext *>(
316274201Sdim      __asan::asanThreadRegistry().FindThreadContextByOsIDLocked(os_id));
317296417Sdim  if (!context) return nullptr;
318274201Sdim  return context->thread;
319274201Sdim}
320296417Sdim} // namespace __asan
321251034Sed
322251034Sed// --- Implementation of LSan-specific functions --- {{{1
323251034Sednamespace __lsan {
324251034Sedbool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,
325251034Sed                           uptr *tls_begin, uptr *tls_end,
326251034Sed                           uptr *cache_begin, uptr *cache_end) {
327274201Sdim  __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id);
328274201Sdim  if (!t) return false;
329274201Sdim  *stack_begin = t->stack_bottom();
330274201Sdim  *stack_end = t->stack_top();
331274201Sdim  *tls_begin = t->tls_begin();
332274201Sdim  *tls_end = t->tls_end();
333274201Sdim  // ASan doesn't keep allocator caches in TLS, so these are unused.
334274201Sdim  *cache_begin = 0;
335274201Sdim  *cache_end = 0;
336274201Sdim  return true;
337251034Sed}
338251034Sed
339274201Sdimvoid ForEachExtraStackRange(uptr os_id, RangeIteratorCallback callback,
340274201Sdim                            void *arg) {
341274201Sdim  __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id);
342274201Sdim  if (t && t->has_fake_stack())
343274201Sdim    t->fake_stack()->ForEachFakeFrame(callback, arg);
344274201Sdim}
345274201Sdim
346251034Sedvoid LockThreadRegistry() {
347251034Sed  __asan::asanThreadRegistry().Lock();
348251034Sed}
349251034Sed
350251034Sedvoid UnlockThreadRegistry() {
351251034Sed  __asan::asanThreadRegistry().Unlock();
352251034Sed}
353274201Sdim
354274201Sdimvoid EnsureMainThreadIDIsCorrect() {
355274201Sdim  __asan::EnsureMainThreadIDIsCorrect();
356274201Sdim}
357296417Sdim} // namespace __lsan
358