forked from OSchip/llvm-project
[hwasan] add basic ThreadRegistry plumbing, also rename HwasanThread to Thread
llvm-svn: 341005
This commit is contained in:
parent
bed556133d
commit
d0cd2db23b
|
@ -36,17 +36,17 @@ using namespace __sanitizer;
|
||||||
namespace __hwasan {
|
namespace __hwasan {
|
||||||
|
|
||||||
void EnterSymbolizer() {
|
void EnterSymbolizer() {
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
CHECK(t);
|
CHECK(t);
|
||||||
t->EnterSymbolizer();
|
t->EnterSymbolizer();
|
||||||
}
|
}
|
||||||
void ExitSymbolizer() {
|
void ExitSymbolizer() {
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
CHECK(t);
|
CHECK(t);
|
||||||
t->LeaveSymbolizer();
|
t->LeaveSymbolizer();
|
||||||
}
|
}
|
||||||
bool IsInSymbolizer() {
|
bool IsInSymbolizer() {
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
return t && t->InSymbolizer();
|
return t && t->InSymbolizer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ static void InitializeFlags() {
|
||||||
|
|
||||||
void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
|
void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
|
||||||
void *context, bool request_fast_unwind) {
|
void *context, bool request_fast_unwind) {
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) {
|
if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) {
|
||||||
// Block reports from our interceptors during _Unwind_Backtrace.
|
// Block reports from our interceptors during _Unwind_Backtrace.
|
||||||
SymbolizerScope sym_scope;
|
SymbolizerScope sym_scope;
|
||||||
|
@ -178,6 +178,7 @@ void __hwasan_init() {
|
||||||
if (hwasan_inited) return;
|
if (hwasan_inited) return;
|
||||||
hwasan_init_is_running = 1;
|
hwasan_init_is_running = 1;
|
||||||
SanitizerToolName = "HWAddressSanitizer";
|
SanitizerToolName = "HWAddressSanitizer";
|
||||||
|
GetThreadRegistry();
|
||||||
|
|
||||||
InitTlsSize();
|
InitTlsSize();
|
||||||
|
|
||||||
|
@ -208,7 +209,7 @@ void __hwasan_init() {
|
||||||
|
|
||||||
HwasanAllocatorInit();
|
HwasanAllocatorInit();
|
||||||
|
|
||||||
HwasanThread *main_thread = HwasanThread::Create(nullptr, nullptr);
|
Thread *main_thread = Thread::Create(nullptr, nullptr);
|
||||||
SetCurrentThread(main_thread);
|
SetCurrentThread(main_thread);
|
||||||
main_thread->Init();
|
main_thread->Init();
|
||||||
|
|
||||||
|
@ -428,7 +429,7 @@ void __hwasan_handle_longjmp(const void *sp_dst) {
|
||||||
static const u8 kFallbackTag = 0xBB;
|
static const u8 kFallbackTag = 0xBB;
|
||||||
|
|
||||||
u8 __hwasan_generate_tag() {
|
u8 __hwasan_generate_tag() {
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
if (!t) return kFallbackTag;
|
if (!t) return kFallbackTag;
|
||||||
return t->GenerateRandomTag();
|
return t->GenerateRandomTag();
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ static void *HwasanAllocate(StackTrace *stack, uptr size, uptr alignment,
|
||||||
}
|
}
|
||||||
ReportAllocationSizeTooBig(size, kMaxAllowedMallocSize, stack);
|
ReportAllocationSizeTooBig(size, kMaxAllowedMallocSize, stack);
|
||||||
}
|
}
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
void *allocated;
|
void *allocated;
|
||||||
if (t) {
|
if (t) {
|
||||||
AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
|
AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
|
||||||
|
@ -199,7 +199,7 @@ void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) {
|
||||||
meta->free_context_id = free_context_id;
|
meta->free_context_id = free_context_id;
|
||||||
// This memory will not be reused by anyone else, so we are free to keep it
|
// This memory will not be reused by anyone else, so we are free to keep it
|
||||||
// poisoned.
|
// poisoned.
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
if (flags()->max_free_fill_size > 0) {
|
if (flags()->max_free_fill_size > 0) {
|
||||||
uptr fill_size = Min(size, (uptr)flags()->max_free_fill_size);
|
uptr fill_size = Min(size, (uptr)flags()->max_free_fill_size);
|
||||||
internal_memset(untagged_ptr, flags()->free_fill_byte, fill_size);
|
internal_memset(untagged_ptr, flags()->free_fill_byte, fill_size);
|
||||||
|
|
|
@ -50,18 +50,18 @@ DECLARE_REAL(void *, memcpy, void *dest, const void *src, uptr n)
|
||||||
DECLARE_REAL(void *, memset, void *dest, int c, uptr n)
|
DECLARE_REAL(void *, memset, void *dest, int c, uptr n)
|
||||||
|
|
||||||
bool IsInInterceptorScope() {
|
bool IsInInterceptorScope() {
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
return t && t->InInterceptorScope();
|
return t && t->InInterceptorScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InterceptorScope {
|
struct InterceptorScope {
|
||||||
InterceptorScope() {
|
InterceptorScope() {
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
if (t)
|
if (t)
|
||||||
t->EnterInterceptorScope();
|
t->EnterInterceptorScope();
|
||||||
}
|
}
|
||||||
~InterceptorScope() {
|
~InterceptorScope() {
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
if (t)
|
if (t)
|
||||||
t->LeaveInterceptorScope();
|
t->LeaveInterceptorScope();
|
||||||
}
|
}
|
||||||
|
@ -294,7 +294,7 @@ extern "C" int pthread_attr_destroy(void *attr);
|
||||||
|
|
||||||
static void *HwasanThreadStartFunc(void *arg) {
|
static void *HwasanThreadStartFunc(void *arg) {
|
||||||
__hwasan_thread_enter();
|
__hwasan_thread_enter();
|
||||||
return ((HwasanThread *)arg)->ThreadStart();
|
return ((Thread *)arg)->ThreadStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
|
INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
|
||||||
|
@ -308,7 +308,7 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
|
||||||
|
|
||||||
AdjustStackSize(attr);
|
AdjustStackSize(attr);
|
||||||
|
|
||||||
HwasanThread *t = HwasanThread::Create(callback, param);
|
Thread *t = Thread::Create(callback, param);
|
||||||
|
|
||||||
int res = REAL(pthread_create)(th, attr, HwasanThreadStartFunc, t);
|
int res = REAL(pthread_create)(th, attr, HwasanThreadStartFunc, t);
|
||||||
|
|
||||||
|
|
|
@ -214,13 +214,13 @@ void InstallAtExitHandler() {
|
||||||
// ---------------------- TSD ---------------- {{{1
|
// ---------------------- TSD ---------------- {{{1
|
||||||
|
|
||||||
extern "C" void __hwasan_thread_enter() {
|
extern "C" void __hwasan_thread_enter() {
|
||||||
HwasanThread *t = HwasanThread::Create(nullptr, nullptr);
|
Thread *t = Thread::Create(nullptr, nullptr);
|
||||||
SetCurrentThread(t);
|
SetCurrentThread(t);
|
||||||
t->Init();
|
t->Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void __hwasan_thread_exit() {
|
extern "C" void __hwasan_thread_exit() {
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
// Make sure that signal handler can not see a stale current thread pointer.
|
// Make sure that signal handler can not see a stale current thread pointer.
|
||||||
atomic_signal_fence(memory_order_seq_cst);
|
atomic_signal_fence(memory_order_seq_cst);
|
||||||
if (t)
|
if (t)
|
||||||
|
@ -232,7 +232,7 @@ static pthread_key_t tsd_key;
|
||||||
static bool tsd_key_inited = false;
|
static bool tsd_key_inited = false;
|
||||||
|
|
||||||
void HwasanTSDDtor(void *tsd) {
|
void HwasanTSDDtor(void *tsd) {
|
||||||
HwasanThread *t = (HwasanThread*)tsd;
|
Thread *t = (Thread*)tsd;
|
||||||
if (t->destructor_iterations_ > 1) {
|
if (t->destructor_iterations_ > 1) {
|
||||||
t->destructor_iterations_--;
|
t->destructor_iterations_--;
|
||||||
CHECK_EQ(0, pthread_setspecific(tsd_key, tsd));
|
CHECK_EQ(0, pthread_setspecific(tsd_key, tsd));
|
||||||
|
@ -247,24 +247,24 @@ void HwasanTSDInit() {
|
||||||
CHECK_EQ(0, pthread_key_create(&tsd_key, HwasanTSDDtor));
|
CHECK_EQ(0, pthread_key_create(&tsd_key, HwasanTSDDtor));
|
||||||
}
|
}
|
||||||
|
|
||||||
HwasanThread *GetCurrentThread() {
|
Thread *GetCurrentThread() {
|
||||||
return (HwasanThread *)pthread_getspecific(tsd_key);
|
return (Thread *)pthread_getspecific(tsd_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCurrentThread(HwasanThread *t) {
|
void SetCurrentThread(Thread *t) {
|
||||||
// Make sure that HwasanTSDDtor gets called at the end.
|
// Make sure that HwasanTSDDtor gets called at the end.
|
||||||
CHECK(tsd_key_inited);
|
CHECK(tsd_key_inited);
|
||||||
// Make sure we do not reset the current HwasanThread.
|
// Make sure we do not reset the current Thread.
|
||||||
CHECK_EQ(0, pthread_getspecific(tsd_key));
|
CHECK_EQ(0, pthread_getspecific(tsd_key));
|
||||||
pthread_setspecific(tsd_key, (void *)t);
|
pthread_setspecific(tsd_key, (void *)t);
|
||||||
}
|
}
|
||||||
#elif SANITIZER_ANDROID
|
#elif SANITIZER_ANDROID
|
||||||
void HwasanTSDInit() {}
|
void HwasanTSDInit() {}
|
||||||
HwasanThread *GetCurrentThread() {
|
Thread *GetCurrentThread() {
|
||||||
return (HwasanThread*)*get_android_tls_ptr();
|
return (Thread*)*get_android_tls_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCurrentThread(HwasanThread *t) {
|
void SetCurrentThread(Thread *t) {
|
||||||
*get_android_tls_ptr() = (uptr)t;
|
*get_android_tls_ptr() = (uptr)t;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -206,10 +206,12 @@ void ReportTagMismatch(StackTrace *stack, uptr tagged_addr, uptr access_size,
|
||||||
// * remove reduntant fields from the allocator metadata
|
// * remove reduntant fields from the allocator metadata
|
||||||
// * use the allocations found in the ring buffer for the main report.
|
// * use the allocations found in the ring buffer for the main report.
|
||||||
HeapAllocationRecord har;
|
HeapAllocationRecord har;
|
||||||
HwasanThread *t = GetCurrentThread();
|
Thread *t = GetCurrentThread();
|
||||||
if (t && FindHeapAllocation(t->heap_allocations(), tagged_addr, &har))
|
if (FindHeapAllocation(t->heap_allocations(), tagged_addr, &har))
|
||||||
Printf("Address found in the ring buffer: %p %u %u\n", har.tagged_addr,
|
Printf("Address found in the ring buffer: %p %u %u\n", har.tagged_addr,
|
||||||
har.free_context_id, har.requested_size);
|
har.free_context_id, har.requested_size);
|
||||||
|
Printf("Current thread: tid: %d\n", t->context()->tid);
|
||||||
|
|
||||||
|
|
||||||
PrintTagsAroundAddr(tag_ptr);
|
PrintTagsAroundAddr(tag_ptr);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "hwasan_interface_internal.h"
|
#include "hwasan_interface_internal.h"
|
||||||
|
|
||||||
#include "sanitizer_common/sanitizer_file.h"
|
#include "sanitizer_common/sanitizer_file.h"
|
||||||
|
#include "sanitizer_common/sanitizer_placement_new.h"
|
||||||
#include "sanitizer_common/sanitizer_tls_get_addr.h"
|
#include "sanitizer_common/sanitizer_tls_get_addr.h"
|
||||||
|
|
||||||
namespace __hwasan {
|
namespace __hwasan {
|
||||||
|
@ -23,21 +24,24 @@ static u32 RandomSeed() {
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
HwasanThread *HwasanThread::Create(thread_callback_t start_routine,
|
Thread *Thread::Create(thread_callback_t start_routine,
|
||||||
void *arg) {
|
void *arg) {
|
||||||
uptr PageSize = GetPageSizeCached();
|
uptr PageSize = GetPageSizeCached();
|
||||||
uptr size = RoundUpTo(sizeof(HwasanThread), PageSize);
|
uptr size = RoundUpTo(sizeof(Thread), PageSize);
|
||||||
HwasanThread *thread = (HwasanThread*)MmapOrDie(size, __func__);
|
Thread *thread = (Thread*)MmapOrDie(size, __func__);
|
||||||
thread->start_routine_ = start_routine;
|
thread->start_routine_ = start_routine;
|
||||||
thread->arg_ = arg;
|
thread->arg_ = arg;
|
||||||
thread->destructor_iterations_ = GetPthreadDestructorIterations();
|
thread->destructor_iterations_ = GetPthreadDestructorIterations();
|
||||||
thread->random_state_ = flags()->random_tags ? RandomSeed() : 0;
|
thread->random_state_ = flags()->random_tags ? RandomSeed() : 0;
|
||||||
|
thread->context_ = nullptr;
|
||||||
|
ThreadContext::Args args = {thread};
|
||||||
|
thread->tid_ = GetThreadRegistry().CreateThread(0, false, 0, &args);
|
||||||
if (auto sz = flags()->heap_history_size)
|
if (auto sz = flags()->heap_history_size)
|
||||||
thread->heap_allocations_ = RingBuffer<HeapAllocationRecord>::New(sz);
|
thread->heap_allocations_ = RingBuffer<HeapAllocationRecord>::New(sz);
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HwasanThread::SetThreadStackAndTls() {
|
void Thread::SetThreadStackAndTls() {
|
||||||
// If this process is "init" (pid 1), /proc may not be mounted yet.
|
// If this process is "init" (pid 1), /proc may not be mounted yet.
|
||||||
if (IsMainThread() && !FileExists("/proc/self/maps")) {
|
if (IsMainThread() && !FileExists("/proc/self/maps")) {
|
||||||
stack_top_ = stack_bottom_ = 0;
|
stack_top_ = stack_bottom_ = 0;
|
||||||
|
@ -58,7 +62,7 @@ void HwasanThread::SetThreadStackAndTls() {
|
||||||
CHECK(MemIsApp(stack_top_ - 1));
|
CHECK(MemIsApp(stack_top_ - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HwasanThread::Init() {
|
void Thread::Init() {
|
||||||
SetThreadStackAndTls();
|
SetThreadStackAndTls();
|
||||||
if (stack_bottom_) {
|
if (stack_bottom_) {
|
||||||
CHECK(MemIsApp(stack_bottom_));
|
CHECK(MemIsApp(stack_bottom_));
|
||||||
|
@ -66,24 +70,24 @@ void HwasanThread::Init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HwasanThread::ClearShadowForThreadStackAndTLS() {
|
void Thread::ClearShadowForThreadStackAndTLS() {
|
||||||
if (stack_top_ != stack_bottom_)
|
if (stack_top_ != stack_bottom_)
|
||||||
TagMemory(stack_bottom_, stack_top_ - stack_bottom_, 0);
|
TagMemory(stack_bottom_, stack_top_ - stack_bottom_, 0);
|
||||||
if (tls_begin_ != tls_end_)
|
if (tls_begin_ != tls_end_)
|
||||||
TagMemory(tls_begin_, tls_end_ - tls_begin_, 0);
|
TagMemory(tls_begin_, tls_end_ - tls_begin_, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HwasanThread::Destroy() {
|
void Thread::Destroy() {
|
||||||
malloc_storage().CommitBack();
|
malloc_storage().CommitBack();
|
||||||
ClearShadowForThreadStackAndTLS();
|
ClearShadowForThreadStackAndTLS();
|
||||||
uptr size = RoundUpTo(sizeof(HwasanThread), GetPageSizeCached());
|
uptr size = RoundUpTo(sizeof(Thread), GetPageSizeCached());
|
||||||
if (heap_allocations_)
|
if (heap_allocations_)
|
||||||
heap_allocations_->Delete();
|
heap_allocations_->Delete();
|
||||||
UnmapOrDie(this, size);
|
UnmapOrDie(this, size);
|
||||||
DTLS_Destroy();
|
DTLS_Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_return_t HwasanThread::ThreadStart() {
|
thread_return_t Thread::ThreadStart() {
|
||||||
return start_routine_(arg_);
|
return start_routine_(arg_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +99,7 @@ static u32 xorshift(u32 state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a (pseudo-)random non-zero tag.
|
// Generate a (pseudo-)random non-zero tag.
|
||||||
tag_t HwasanThread::GenerateRandomTag() {
|
tag_t Thread::GenerateRandomTag() {
|
||||||
tag_t tag;
|
tag_t tag;
|
||||||
do {
|
do {
|
||||||
if (flags()->random_tags) {
|
if (flags()->random_tags) {
|
||||||
|
@ -111,4 +115,32 @@ tag_t HwasanThread::GenerateRandomTag() {
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThreadContext::OnCreated(void *arg) {
|
||||||
|
Args *args = static_cast<Args*>(arg);
|
||||||
|
thread = args->thread;
|
||||||
|
thread->set_context(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadContext::OnFinished() {
|
||||||
|
thread = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const u32 kMaxLiveThreads = 1024;
|
||||||
|
|
||||||
|
static ThreadContextBase *ThreadContextFactory(u32 tid) {
|
||||||
|
static ALIGNED(16) char placeholder[sizeof(ThreadContext) * kMaxLiveThreads];
|
||||||
|
void *mem = &placeholder[0] + tid * sizeof(ThreadContext);
|
||||||
|
CHECK_LT(tid, kMaxLiveThreads);
|
||||||
|
return new (mem) ThreadContext(tid);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadRegistry &GetThreadRegistry() {
|
||||||
|
static ALIGNED(16) char placeholder[sizeof(ThreadRegistry)];
|
||||||
|
static ThreadRegistry *registry;
|
||||||
|
if (!registry)
|
||||||
|
registry = new (placeholder)
|
||||||
|
ThreadRegistry(ThreadContextFactory, kMaxLiveThreads, kMaxLiveThreads);
|
||||||
|
return *registry;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace __hwasan
|
} // namespace __hwasan
|
||||||
|
|
|
@ -16,12 +16,33 @@
|
||||||
|
|
||||||
#include "hwasan_allocator.h"
|
#include "hwasan_allocator.h"
|
||||||
#include "sanitizer_common/sanitizer_common.h"
|
#include "sanitizer_common/sanitizer_common.h"
|
||||||
|
#include "sanitizer_common/sanitizer_thread_registry.h"
|
||||||
|
|
||||||
namespace __hwasan {
|
namespace __hwasan {
|
||||||
|
|
||||||
class HwasanThread {
|
class Thread;
|
||||||
|
|
||||||
|
class ThreadContext : public ThreadContextBase {
|
||||||
public:
|
public:
|
||||||
static HwasanThread *Create(thread_callback_t start_routine, void *arg);
|
explicit ThreadContext(int tid)
|
||||||
|
: ThreadContextBase(tid), thread(nullptr){}
|
||||||
|
|
||||||
|
Thread *thread;
|
||||||
|
|
||||||
|
void OnCreated(void *arg) override;
|
||||||
|
void OnFinished() override;
|
||||||
|
|
||||||
|
struct Args {
|
||||||
|
Thread *thread;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// We want this to be small.
|
||||||
|
COMPILER_CHECK(sizeof(ThreadContext) <= 256);
|
||||||
|
|
||||||
|
class Thread {
|
||||||
|
public:
|
||||||
|
static Thread *Create(thread_callback_t start_routine, void *arg);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
|
@ -54,12 +75,15 @@ class HwasanThread {
|
||||||
return heap_allocations_;
|
return heap_allocations_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_context(ThreadContext *context) { context_ = context; }
|
||||||
|
const ThreadContext *context() const { return context_; }
|
||||||
|
|
||||||
tag_t GenerateRandomTag();
|
tag_t GenerateRandomTag();
|
||||||
|
|
||||||
int destructor_iterations_;
|
int destructor_iterations_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// NOTE: There is no HwasanThread constructor. It is allocated
|
// NOTE: There is no Thread constructor. It is allocated
|
||||||
// via mmap() and *must* be valid in zero-initialized state.
|
// via mmap() and *must* be valid in zero-initialized state.
|
||||||
void SetThreadStackAndTls();
|
void SetThreadStackAndTls();
|
||||||
void ClearShadowForThreadStackAndTLS();
|
void ClearShadowForThreadStackAndTLS();
|
||||||
|
@ -79,10 +103,18 @@ class HwasanThread {
|
||||||
|
|
||||||
HwasanThreadLocalMallocStorage malloc_storage_;
|
HwasanThreadLocalMallocStorage malloc_storage_;
|
||||||
HeapAllocationsRingBuffer *heap_allocations_;
|
HeapAllocationsRingBuffer *heap_allocations_;
|
||||||
|
|
||||||
|
u32 tid_;
|
||||||
|
ThreadContext *context_;
|
||||||
};
|
};
|
||||||
|
|
||||||
HwasanThread *GetCurrentThread();
|
Thread *GetCurrentThread();
|
||||||
void SetCurrentThread(HwasanThread *t);
|
void SetCurrentThread(Thread *t);
|
||||||
|
|
||||||
|
// Returns the ThreadRegistry singleton.
|
||||||
|
ThreadRegistry &GetThreadRegistry();
|
||||||
|
|
||||||
|
// Returns the ThreadRegistry singleton.
|
||||||
|
|
||||||
} // namespace __hwasan
|
} // namespace __hwasan
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue