parent
763da45e9e
commit
79437fe376
|
@ -160,8 +160,8 @@ struct ChunkBase {
|
|||
u8 chunk_state;
|
||||
u8 size_class;
|
||||
u32 offset; // User-visible memory starts at this+offset (beg()).
|
||||
s32 alloc_tid;
|
||||
s32 free_tid;
|
||||
u32 alloc_tid;
|
||||
u32 free_tid;
|
||||
uptr used_size; // Size requested by the user.
|
||||
AsanChunk *next;
|
||||
|
||||
|
@ -585,7 +585,7 @@ static void Describe(uptr addr, uptr access_size) {
|
|||
m->compressed_alloc_stack_size());
|
||||
AsanThread *t = asanThreadRegistry().GetCurrent();
|
||||
CHECK(t);
|
||||
if (m->free_tid >= 0) {
|
||||
if (m->free_tid != kInvalidTid) {
|
||||
AsanThreadSummary *free_thread =
|
||||
asanThreadRegistry().FindByTid(m->free_tid);
|
||||
AsanPrintf("freed by thread T%d here:\n", free_thread->tid());
|
||||
|
@ -682,7 +682,7 @@ static u8 *Allocate(uptr alignment, uptr size, AsanStackTrace *stack) {
|
|||
m->offset = addr - (uptr)m;
|
||||
CHECK(m->beg() == addr);
|
||||
m->alloc_tid = t ? t->tid() : 0;
|
||||
m->free_tid = AsanThread::kInvalidTid;
|
||||
m->free_tid = kInvalidTid;
|
||||
AsanStackTrace::CompressStack(stack, m->compressed_alloc_stack(),
|
||||
m->compressed_alloc_stack_size());
|
||||
PoisonShadow(addr, rounded_size, 0);
|
||||
|
@ -722,7 +722,7 @@ static void Deallocate(u8 *ptr, AsanStackTrace *stack) {
|
|||
ShowStatsAndAbort();
|
||||
}
|
||||
CHECK(old_chunk_state == CHUNK_ALLOCATED);
|
||||
CHECK(m->free_tid == AsanThread::kInvalidTid);
|
||||
CHECK(m->free_tid == kInvalidTid);
|
||||
CHECK(m->alloc_tid >= 0);
|
||||
AsanThread *t = asanThreadRegistry().GetCurrent();
|
||||
m->free_tid = t ? t->tid() : 0;
|
||||
|
|
|
@ -299,7 +299,7 @@ static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
|
|||
INTERCEPTOR(int, pthread_create, void *thread,
|
||||
void *attr, void *(*start_routine)(void*), void *arg) {
|
||||
GET_STACK_TRACE_HERE(kStackTraceMax);
|
||||
int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
|
||||
u32 current_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
|
||||
AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack);
|
||||
asanThreadRegistry().RegisterThread(t);
|
||||
return REAL(pthread_create)(thread, attr, asan_thread_start, t);
|
||||
|
@ -722,7 +722,7 @@ INTERCEPTOR_WINAPI(DWORD, CreateThread,
|
|||
DWORD (__stdcall *start_routine)(void*), void* arg,
|
||||
DWORD flags, void* tid) {
|
||||
GET_STACK_TRACE_HERE(kStackTraceMax);
|
||||
int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
|
||||
u32 current_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
|
||||
AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack);
|
||||
asanThreadRegistry().RegisterThread(t);
|
||||
return REAL(CreateThread)(security, stack_size,
|
||||
|
|
|
@ -403,7 +403,7 @@ typedef void* (*worker_t)(void *block);
|
|||
typedef struct {
|
||||
void *block;
|
||||
dispatch_function_t func;
|
||||
int parent_tid;
|
||||
u32 parent_tid;
|
||||
} asan_block_context_t;
|
||||
|
||||
// We use extern declarations of libdispatch functions here instead
|
||||
|
@ -461,7 +461,7 @@ asan_block_context_t *alloc_asan_context(void *ctxt, dispatch_function_t func,
|
|||
(asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), stack);
|
||||
asan_ctxt->block = ctxt;
|
||||
asan_ctxt->func = func;
|
||||
asan_ctxt->parent_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
|
||||
asan_ctxt->parent_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
|
||||
return asan_ctxt;
|
||||
}
|
||||
|
||||
|
@ -559,7 +559,7 @@ INTERCEPTOR(int, pthread_workqueue_additem_np, pthread_workqueue_t workq,
|
|||
(asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), &stack);
|
||||
asan_ctxt->block = workitem_arg;
|
||||
asan_ctxt->func = (dispatch_function_t)workitem_func;
|
||||
asan_ctxt->parent_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
|
||||
asan_ctxt->parent_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
|
||||
if (FLAG_v >= 2) {
|
||||
Report("pthread_workqueue_additem_np: %p\n", asan_ctxt);
|
||||
PRINT_CURRENT_STACK();
|
||||
|
|
|
@ -89,7 +89,7 @@ static void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) {
|
|||
AsanReport("ERROR: AddressSanitizer crashed on unknown address %p"
|
||||
" (pc %p sp %p bp %p T%d)\n",
|
||||
(void*)addr, (void*)pc, (void*)sp, (void*)bp,
|
||||
asanThreadRegistry().GetCurrentTidOrMinusOne());
|
||||
asanThreadRegistry().GetCurrentTidOrInvalid());
|
||||
AsanPrintf("AddressSanitizer can not provide additional info. ABORTING\n");
|
||||
GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp);
|
||||
stack.PrintStack();
|
||||
|
@ -111,7 +111,7 @@ void SetAlternateSignalStack() {
|
|||
CHECK(0 == sigaltstack(&altstack, 0));
|
||||
if (FLAG_v > 0) {
|
||||
Report("Alternative stack for T%d set: [%p,%p)\n",
|
||||
asanThreadRegistry().GetCurrentTidOrMinusOne(),
|
||||
asanThreadRegistry().GetCurrentTidOrInvalid(),
|
||||
altstack.ss_sp, (char*)altstack.ss_sp + altstack.ss_size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -422,7 +422,7 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp,
|
|||
}
|
||||
|
||||
AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
|
||||
int curr_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
|
||||
u32 curr_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
|
||||
|
||||
if (curr_thread) {
|
||||
// We started reporting an error message. Stop using the fake stack
|
||||
|
|
|
@ -26,7 +26,7 @@ AsanThread::AsanThread(LinkerInitialized x)
|
|||
malloc_storage_(x),
|
||||
stats_(x) { }
|
||||
|
||||
AsanThread *AsanThread::Create(int parent_tid, thread_callback_t start_routine,
|
||||
AsanThread *AsanThread::Create(u32 parent_tid, thread_callback_t start_routine,
|
||||
void *arg, AsanStackTrace *stack) {
|
||||
uptr size = RoundUpTo(sizeof(AsanThread), kPageSize);
|
||||
AsanThread *thread = (AsanThread*)AsanMmapSomewhereOrDie(size, __FUNCTION__);
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
namespace __asan {
|
||||
|
||||
const u32 kInvalidTid = 0xffffff; // Must fit into 24 bits.
|
||||
|
||||
class AsanThread;
|
||||
|
||||
// These objects are created for every thread and are never deleted,
|
||||
|
@ -28,10 +30,10 @@ class AsanThread;
|
|||
class AsanThreadSummary {
|
||||
public:
|
||||
explicit AsanThreadSummary(LinkerInitialized) { } // for T0.
|
||||
AsanThreadSummary(int parent_tid, AsanStackTrace *stack)
|
||||
AsanThreadSummary(u32 parent_tid, AsanStackTrace *stack)
|
||||
: parent_tid_(parent_tid),
|
||||
announced_(false) {
|
||||
tid_ = -1;
|
||||
tid_ = kInvalidTid;
|
||||
if (stack) {
|
||||
stack_ = *stack;
|
||||
}
|
||||
|
@ -45,15 +47,15 @@ class AsanThreadSummary {
|
|||
stack_.PrintStack();
|
||||
}
|
||||
}
|
||||
int tid() { return tid_; }
|
||||
void set_tid(int tid) { tid_ = tid; }
|
||||
u32 tid() { return tid_; }
|
||||
void set_tid(u32 tid) { tid_ = tid; }
|
||||
AsanThread *thread() { return thread_; }
|
||||
void set_thread(AsanThread *thread) { thread_ = thread; }
|
||||
static void TSDDtor(void *tsd);
|
||||
|
||||
private:
|
||||
int tid_;
|
||||
int parent_tid_;
|
||||
u32 tid_;
|
||||
u32 parent_tid_;
|
||||
bool announced_;
|
||||
AsanStackTrace stack_;
|
||||
AsanThread *thread_;
|
||||
|
@ -63,7 +65,7 @@ class AsanThreadSummary {
|
|||
class AsanThread {
|
||||
public:
|
||||
explicit AsanThread(LinkerInitialized); // for T0.
|
||||
static AsanThread *Create(int parent_tid, thread_callback_t start_routine,
|
||||
static AsanThread *Create(u32 parent_tid, thread_callback_t start_routine,
|
||||
void *arg, AsanStackTrace *stack);
|
||||
void Destroy();
|
||||
|
||||
|
@ -73,7 +75,7 @@ class AsanThread {
|
|||
uptr stack_top() { return stack_top_; }
|
||||
uptr stack_bottom() { return stack_bottom_; }
|
||||
uptr stack_size() { return stack_top_ - stack_bottom_; }
|
||||
int tid() { return summary_->tid(); }
|
||||
u32 tid() { return summary_->tid(); }
|
||||
AsanThreadSummary *summary() { return summary_; }
|
||||
void set_summary(AsanThreadSummary *summary) { summary_ = summary; }
|
||||
|
||||
|
@ -87,8 +89,6 @@ class AsanThread {
|
|||
AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
|
||||
AsanStats &stats() { return stats_; }
|
||||
|
||||
static const int kInvalidTid = -1;
|
||||
|
||||
private:
|
||||
|
||||
void SetThreadStackTopAndBottom();
|
||||
|
|
|
@ -43,7 +43,7 @@ void AsanThreadRegistry::Init() {
|
|||
|
||||
void AsanThreadRegistry::RegisterThread(AsanThread *thread) {
|
||||
ScopedLock lock(&mu_);
|
||||
int tid = n_threads_;
|
||||
u32 tid = n_threads_;
|
||||
n_threads_++;
|
||||
CHECK(n_threads_ < kMaxNumberOfThreads);
|
||||
|
||||
|
@ -130,8 +130,7 @@ uptr AsanThreadRegistry::GetFreeBytes() {
|
|||
+ accumulated_stats_.really_freed_redzones;
|
||||
}
|
||||
|
||||
AsanThreadSummary *AsanThreadRegistry::FindByTid(int tid) {
|
||||
CHECK(tid >= 0);
|
||||
AsanThreadSummary *AsanThreadRegistry::FindByTid(u32 tid) {
|
||||
CHECK(tid < n_threads_);
|
||||
CHECK(thread_summaries_[tid]);
|
||||
return thread_summaries_[tid];
|
||||
|
@ -139,10 +138,7 @@ AsanThreadSummary *AsanThreadRegistry::FindByTid(int tid) {
|
|||
|
||||
AsanThread *AsanThreadRegistry::FindThreadByStackAddress(uptr addr) {
|
||||
ScopedLock lock(&mu_);
|
||||
// Main thread (tid = 0) stack limits are pretty much guessed; for the other
|
||||
// threads we ask libpthread, so their limits must be correct.
|
||||
// Scanning the thread list backwards makes this function more reliable.
|
||||
for (int tid = n_threads_ - 1; tid >= 0; tid--) {
|
||||
for (u32 tid = 0; tid < n_threads_; tid++) {
|
||||
AsanThread *t = thread_summaries_[tid]->thread();
|
||||
if (!t || !(t->fake_stack().StackSize())) continue;
|
||||
if (t->fake_stack().AddrIsInFakeStack(addr) || t->AddrIsInStack(addr)) {
|
||||
|
@ -153,7 +149,7 @@ AsanThread *AsanThreadRegistry::FindThreadByStackAddress(uptr addr) {
|
|||
}
|
||||
|
||||
void AsanThreadRegistry::UpdateAccumulatedStatsUnlocked() {
|
||||
for (int tid = 0; tid < n_threads_; tid++) {
|
||||
for (u32 tid = 0; tid < n_threads_; tid++) {
|
||||
AsanThread *t = thread_summaries_[tid]->thread();
|
||||
if (t != 0) {
|
||||
FlushToAccumulatedStatsUnlocked(&t->stats());
|
||||
|
|
|
@ -38,10 +38,10 @@ class AsanThreadRegistry {
|
|||
AsanThread *GetCurrent();
|
||||
void SetCurrent(AsanThread *t);
|
||||
|
||||
int GetCurrentTidOrMinusOne() {
|
||||
u32 GetCurrentTidOrInvalid() {
|
||||
if (!inited_) return 0;
|
||||
AsanThread *t = GetCurrent();
|
||||
return t ? t->tid() : -1;
|
||||
return t ? t->tid() : kInvalidTid;
|
||||
}
|
||||
|
||||
// Returns stats for GetCurrent(), or stats for
|
||||
|
@ -54,7 +54,7 @@ class AsanThreadRegistry {
|
|||
uptr GetHeapSize();
|
||||
uptr GetFreeBytes();
|
||||
|
||||
AsanThreadSummary *FindByTid(int tid);
|
||||
AsanThreadSummary *FindByTid(u32 tid);
|
||||
AsanThread *FindThreadByStackAddress(uptr addr);
|
||||
|
||||
private:
|
||||
|
@ -68,7 +68,7 @@ class AsanThreadRegistry {
|
|||
AsanThread main_thread_;
|
||||
AsanThreadSummary main_thread_summary_;
|
||||
AsanStats accumulated_stats_;
|
||||
int n_threads_;
|
||||
u32 n_threads_;
|
||||
AsanLock mu_;
|
||||
bool inited_;
|
||||
};
|
||||
|
|
|
@ -219,7 +219,7 @@ u16 AtomicExchange(u16 *a, u16 new_val) {
|
|||
return new_val;
|
||||
}
|
||||
|
||||
u16 AtomicExchange(u16 *a, u16 new_val) {
|
||||
u8 AtomicExchange(u8 *a, u8 new_val) {
|
||||
// FIXME: can we do this with a proper xchg intrinsic?
|
||||
u8 t = *a;
|
||||
*a = new_val;
|
||||
|
|
Loading…
Reference in New Issue