diff options
Diffstat (limited to 'lib/asan/asan_thread.h')
-rw-r--r-- | lib/asan/asan_thread.h | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/lib/asan/asan_thread.h b/lib/asan/asan_thread.h index 11771ecd09f09..9da136c87ef17 100644 --- a/lib/asan/asan_thread.h +++ b/lib/asan/asan_thread.h @@ -17,7 +17,6 @@ #include "asan_allocator.h" #include "asan_internal.h" #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" @@ -56,12 +55,14 @@ COMPILER_CHECK(sizeof(AsanThreadContext) <= 256); // AsanThread are stored in TSD and destroyed when the thread dies. class AsanThread { public: - static AsanThread *Create(thread_callback_t start_routine, void *arg); + static AsanThread *Create(thread_callback_t start_routine, void *arg, + u32 parent_tid, StackTrace *stack, bool detached); static void TSDDtor(void *tsd); void Destroy(); void Init(); // Should be called from the thread itself. - thread_return_t ThreadStart(uptr os_id); + thread_return_t ThreadStart(uptr os_id, + atomic_uintptr_t *signal_thread_is_registered); uptr stack_top() { return stack_top_; } uptr stack_bottom() { return stack_bottom_; } @@ -72,18 +73,23 @@ class AsanThread { AsanThreadContext *context() { return context_; } void set_context(AsanThreadContext *context) { context_ = context; } - const char *GetFrameNameByAddr(uptr addr, uptr *offset, uptr *frame_pc); + struct StackFrameAccess { + uptr offset; + uptr frame_pc; + const char *frame_descr; + }; + bool GetStackFrameAccessByAddr(uptr addr, StackFrameAccess *access); bool AddrIsInStack(uptr addr) { return addr >= stack_bottom_ && addr < stack_top_; } - void DeleteFakeStack() { + void DeleteFakeStack(int tid) { if (!fake_stack_) return; FakeStack *t = fake_stack_; fake_stack_ = 0; SetTLSFakeStack(0); - t->Destroy(); + t->Destroy(tid); } bool has_fake_stack() { @@ -101,14 +107,19 @@ class AsanThread { // 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; } + bool isUnwinding() const { return unwinding_; } + void setUnwinding(bool b) { unwinding_ = b; } + + // True if we are in a deadly signal handler. + bool isInDeadlySignal() const { return in_deadly_signal_; } + void setInDeadlySignal(bool b) { in_deadly_signal_ = b; } AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } AsanStats &stats() { return stats_; } private: - AsanThread() : unwinding(false) {} + // NOTE: There is no AsanThread constructor. It is allocated + // via mmap() and *must* be valid in zero-initialized state. void SetThreadStackAndTls(); void ClearShadowForThreadStackAndTLS(); FakeStack *AsyncSignalSafeLazyInitFakeStack(); @@ -116,18 +127,19 @@ class AsanThread { AsanThreadContext *context_; thread_callback_t start_routine_; void *arg_; - uptr stack_top_; - uptr stack_bottom_; + 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 stack_size_; uptr tls_begin_; uptr tls_end_; FakeStack *fake_stack_; AsanThreadLocalMallocStorage malloc_storage_; AsanStats stats_; - bool unwinding; + bool unwinding_; + bool in_deadly_signal_; }; // ScopedUnwinding is a scope for stacktracing member of a context @@ -142,9 +154,18 @@ class ScopedUnwinding { AsanThread *thread; }; -struct CreateThreadContextArgs { +// ScopedDeadlySignal is a scope for handling deadly signals. +class ScopedDeadlySignal { + public: + explicit ScopedDeadlySignal(AsanThread *t) : thread(t) { + if (thread) thread->setInDeadlySignal(true); + } + ~ScopedDeadlySignal() { + if (thread) thread->setInDeadlySignal(false); + } + + private: AsanThread *thread; - StackTrace *stack; }; // Returns a single instance of registry. |