diff options
author | Vitaly Buka <vitalybuka@google.com> | 2017-08-09 00:38:57 +0000 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2017-08-09 00:38:57 +0000 |
commit | 5f5d782f41c4db73d704a0d1d15dceb8f3f8e3e7 (patch) | |
tree | f03d50c42dbd1084c7a09ff171d6fff4656b06a6 /lib/asan/asan_thread.cc | |
parent | f569d19ea0c83ee6e59b64135727b0a2cd8434f8 (diff) |
[asan] Refactor thread creation bookkeeping
Summary:
This is a pure refactoring change. It paves the way for OS-specific
implementations, such as Fuchsia's, that can do most of the
per-thread bookkeeping work in the creator thread before the new
thread actually starts. This model is simpler and cleaner, avoiding
some race issues that the interceptor code for thread creation has
to do for the existing OS-specific implementations.
Submitted on behalf of Roland McGrath.
Reviewers: vitalybuka, alekseyshl, kcc
Reviewed By: alekseyshl
Subscribers: phosek, filcab, llvm-commits, kubamracek
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D36385
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@310432 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/asan/asan_thread.cc')
-rw-r--r-- | lib/asan/asan_thread.cc | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cc index 74426f675..c41d3ba94 100644 --- a/lib/asan/asan_thread.cc +++ b/lib/asan/asan_thread.cc @@ -27,11 +27,6 @@ namespace __asan { // AsanThreadContext implementation. -struct CreateThreadContextArgs { - AsanThread *thread; - StackTrace *stack; -}; - void AsanThreadContext::OnCreated(void *arg) { CreateThreadContextArgs *args = static_cast<CreateThreadContextArgs*>(arg); if (args->stack) @@ -88,7 +83,7 @@ AsanThread *AsanThread::Create(thread_callback_t start_routine, void *arg, AsanThread *thread = (AsanThread*)MmapOrDie(size, __func__); thread->start_routine_ = start_routine; thread->arg_ = arg; - CreateThreadContextArgs args = { thread, stack }; + AsanThreadContext::CreateThreadContextArgs args = {thread, stack}; asanThreadRegistry().CreateThread(*reinterpret_cast<uptr *>(thread), detached, parent_tid, &args); @@ -223,12 +218,12 @@ FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() { return nullptr; } -void AsanThread::Init() { +void AsanThread::Init(const InitOptions *options) { next_stack_top_ = next_stack_bottom_ = 0; atomic_store(&stack_switching_, false, memory_order_release); fake_stack_ = nullptr; // Will be initialized lazily if needed. CHECK_EQ(this->stack_size(), 0U); - SetThreadStackAndTls(); + SetThreadStackAndTls(options); CHECK_GT(this->stack_size(), 0U); CHECK(AddrIsInMem(stack_bottom_)); CHECK(AddrIsInMem(stack_top_ - 1)); @@ -274,7 +269,21 @@ thread_return_t AsanThread::ThreadStart( return res; } -void AsanThread::SetThreadStackAndTls() { +AsanThread *CreateMainThread() { + AsanThread *main_thread = AsanThread::Create( + /* start_routine */ nullptr, /* arg */ nullptr, /* parent_tid */ 0, + /* stack */ nullptr, /* detached */ true); + SetCurrentThread(main_thread); + main_thread->ThreadStart(internal_getpid(), + /* signal_thread_is_registered */ nullptr); + return main_thread; +} + +// This implementation doesn't use the argument, which is just passed down +// from the caller of Init (which see, above). It's only there to support +// OS-specific implementations that need more information passed through. +void AsanThread::SetThreadStackAndTls(const InitOptions *options) { + DCHECK_EQ(options, nullptr); uptr tls_size = 0; uptr stack_size = 0; GetThreadStackAndTls(tid() == 0, const_cast<uptr *>(&stack_bottom_), |