aboutsummaryrefslogtreecommitdiff
path: root/lib/asan/asan_thread.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2014-11-06 22:49:13 +0000
committerDimitry Andric <dim@FreeBSD.org>2014-11-06 22:49:13 +0000
commit8ef50bf3d1c287b5013c3168de77a462dfce3495 (patch)
tree3467f3372c1195b1546172d89af2205a50b1866d /lib/asan/asan_thread.h
parent11023dc647fd8f41418da90d59db138400d0f334 (diff)
downloadsrc-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.h70
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