diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2014-11-06 22:49:13 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2014-11-06 22:49:13 +0000 |
commit | 8ef50bf3d1c287b5013c3168de77a462dfce3495 (patch) | |
tree | 3467f3372c1195b1546172d89af2205a50b1866d /lib/asan/asan_thread.h | |
parent | 11023dc647fd8f41418da90d59db138400d0f334 (diff) | |
download | src-8ef50bf3d1c287b5013c3168de77a462dfce3495.tar.gz src-8ef50bf3d1c287b5013c3168de77a462dfce3495.zip |
Import compiler-rt release_34 branch r197381.vendor/compiler-rt/compiler-rt-r197381
Notes
Notes:
svn path=/vendor/compiler-rt/dist/; revision=274201
svn path=/vendor/compiler-rt/compiler-rt-r197381/; revision=274202; tag=vendor/compiler-rt/compiler-rt-r197381
Diffstat (limited to 'lib/asan/asan_thread.h')
-rw-r--r-- | lib/asan/asan_thread.h | 70 |
1 files changed, 61 insertions, 9 deletions
diff --git a/lib/asan/asan_thread.h b/lib/asan/asan_thread.h index 14062b62f751..11771ecd09f0 100644 --- a/lib/asan/asan_thread.h +++ b/lib/asan/asan_thread.h @@ -19,6 +19,7 @@ #include "asan_fake_stack.h" #include "asan_stack.h" #include "asan_stats.h" +#include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_thread_registry.h" @@ -36,11 +37,13 @@ class AsanThreadContext : public ThreadContextBase { explicit AsanThreadContext(int tid) : ThreadContextBase(tid), announced(false), + destructor_iterations(kPthreadDestructorIterations), + stack_id(0), thread(0) { - internal_memset(&stack, 0, sizeof(stack)); } bool announced; - StackTrace stack; + u8 destructor_iterations; + u32 stack_id; AsanThread *thread; void OnCreated(void *arg); @@ -48,7 +51,7 @@ class AsanThreadContext : public ThreadContextBase { }; // AsanThreadContext objects are never freed, so we need many of them. -COMPILER_CHECK(sizeof(AsanThreadContext) <= 4096); +COMPILER_CHECK(sizeof(AsanThreadContext) <= 256); // AsanThread are stored in TSD and destroyed when the thread dies. class AsanThread { @@ -62,7 +65,9 @@ class AsanThread { uptr stack_top() { return stack_top_; } uptr stack_bottom() { return stack_bottom_; } - uptr stack_size() { return stack_top_ - stack_bottom_; } + uptr stack_size() { return stack_size_; } + uptr tls_begin() { return tls_begin_; } + uptr tls_end() { return tls_end_; } u32 tid() { return context_->tid; } AsanThreadContext *context() { return context_; } void set_context(AsanThreadContext *context) { context_ = context; } @@ -73,23 +78,68 @@ class AsanThread { return addr >= stack_bottom_ && addr < stack_top_; } - FakeStack &fake_stack() { return fake_stack_; } + void DeleteFakeStack() { + if (!fake_stack_) return; + FakeStack *t = fake_stack_; + fake_stack_ = 0; + SetTLSFakeStack(0); + t->Destroy(); + } + + bool has_fake_stack() { + return (reinterpret_cast<uptr>(fake_stack_) > 1); + } + + FakeStack *fake_stack() { + if (!__asan_option_detect_stack_use_after_return) + return 0; + if (!has_fake_stack()) + return AsyncSignalSafeLazyInitFakeStack(); + return fake_stack_; + } + + // True is this thread is currently unwinding stack (i.e. collecting a stack + // trace). Used to prevent deadlocks on platforms where libc unwinder calls + // malloc internally. See PR17116 for more details. + bool isUnwinding() const { return unwinding; } + void setUnwinding(bool b) { unwinding = b; } + AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } AsanStats &stats() { return stats_; } private: - AsanThread() {} - void SetThreadStackTopAndBottom(); - void ClearShadowForThreadStack(); + AsanThread() : unwinding(false) {} + void SetThreadStackAndTls(); + void ClearShadowForThreadStackAndTLS(); + FakeStack *AsyncSignalSafeLazyInitFakeStack(); + AsanThreadContext *context_; thread_callback_t start_routine_; void *arg_; uptr stack_top_; uptr stack_bottom_; + // stack_size_ == stack_top_ - stack_bottom_; + // It needs to be set in a async-signal-safe manner. + uptr stack_size_; + uptr tls_begin_; + uptr tls_end_; - FakeStack fake_stack_; + FakeStack *fake_stack_; AsanThreadLocalMallocStorage malloc_storage_; AsanStats stats_; + bool unwinding; +}; + +// ScopedUnwinding is a scope for stacktracing member of a context +class ScopedUnwinding { + public: + explicit ScopedUnwinding(AsanThread *t) : thread(t) { + t->setUnwinding(true); + } + ~ScopedUnwinding() { thread->setUnwinding(false); } + + private: + AsanThread *thread; }; struct CreateThreadContextArgs { @@ -109,6 +159,8 @@ void SetCurrentThread(AsanThread *t); u32 GetCurrentTidOrInvalid(); AsanThread *FindThreadByStackAddress(uptr addr); +// Used to handle fork(). +void EnsureMainThreadIDIsCorrect(); } // namespace __asan #endif // ASAN_THREAD_H |