forked from OSchip/llvm-project
tsan: mark shadow for thread stack as "don't need" when thread exits
llvm-svn: 177288
This commit is contained in:
parent
2f69d405cc
commit
2e7f29f042
|
@ -619,11 +619,7 @@ TSAN_INTERCEPTOR(void*, mmap64, void *addr, long_t sz, int prot,
|
|||
|
||||
TSAN_INTERCEPTOR(int, munmap, void *addr, long_t sz) {
|
||||
SCOPED_TSAN_INTERCEPTOR(munmap, addr, sz);
|
||||
// We are about to unmap a chunk of user memory.
|
||||
// Mark the corresponding shadow memory as not needed.
|
||||
uptr shadow_beg = MemToShadow((uptr)addr);
|
||||
uptr shadow_end = MemToShadow((uptr)addr + sz);
|
||||
FlushUnneededShadowMemory(shadow_beg, shadow_end - shadow_beg);
|
||||
DontNeedShadowFor((uptr)addr, sz);
|
||||
int res = REAL(munmap)(addr, sz);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -34,10 +34,7 @@ struct MapUnmapCallback {
|
|||
void OnUnmap(uptr p, uptr size) const {
|
||||
// We are about to unmap a chunk of user memory.
|
||||
// Mark the corresponding shadow memory as not needed.
|
||||
uptr shadow_beg = MemToShadow(p);
|
||||
uptr shadow_end = MemToShadow(p + size);
|
||||
CHECK(IsAligned(shadow_end|shadow_beg, GetPageSizeCached()));
|
||||
FlushUnneededShadowMemory(shadow_beg, shadow_end - shadow_beg);
|
||||
DontNeedShadowFor(p, size);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -125,6 +125,12 @@ static void InitializeMemoryProfile() {
|
|||
internal_start_thread(&MemoryProfileThread, (void*)(uptr)fd);
|
||||
}
|
||||
|
||||
void DontNeedShadowFor(uptr addr, uptr size) {
|
||||
uptr shadow_beg = MemToShadow(addr);
|
||||
uptr shadow_end = MemToShadow(addr + size);
|
||||
FlushUnneededShadowMemory(shadow_beg, shadow_end - shadow_beg);
|
||||
}
|
||||
|
||||
static void MemoryFlushThread(void *arg) {
|
||||
ScopedInRtl in_rtl;
|
||||
for (int i = 0; ; i++) {
|
||||
|
|
|
@ -527,6 +527,7 @@ void ALWAYS_INLINE INLINE StatSet(ThreadState *thr, StatType typ, u64 n) {
|
|||
|
||||
void MapShadow(uptr addr, uptr size);
|
||||
void MapThreadTrace(uptr addr, uptr size);
|
||||
void DontNeedShadowFor(uptr addr, uptr size);
|
||||
void InitializeShadowMemory();
|
||||
void InitializeInterceptors();
|
||||
void InitializeDynamicAnnotations();
|
||||
|
|
|
@ -200,9 +200,8 @@ void ThreadStart(ThreadState *thr, int tid, uptr os_id) {
|
|||
GetThreadStackAndTls(tid == 0, &stk_addr, &stk_size, &tls_addr, &tls_size);
|
||||
|
||||
if (tid) {
|
||||
if (stk_addr && stk_size) {
|
||||
if (stk_addr && stk_size)
|
||||
MemoryResetRange(thr, /*pc=*/ 1, stk_addr, stk_size);
|
||||
}
|
||||
|
||||
if (tls_addr && tls_size) {
|
||||
// Check that the thr object is in tls;
|
||||
|
@ -225,17 +224,10 @@ void ThreadStart(ThreadState *thr, int tid, uptr os_id) {
|
|||
void ThreadFinish(ThreadState *thr) {
|
||||
CHECK_GT(thr->in_rtl, 0);
|
||||
StatInc(thr, StatThreadFinish);
|
||||
// FIXME: Treat it as write.
|
||||
if (thr->stk_addr && thr->stk_size)
|
||||
MemoryResetRange(thr, /*pc=*/ 3, thr->stk_addr, thr->stk_size);
|
||||
if (thr->tls_addr && thr->tls_size) {
|
||||
const uptr thr_beg = (uptr)thr;
|
||||
const uptr thr_end = (uptr)thr + sizeof(*thr);
|
||||
// Since the thr object is huge, skip it.
|
||||
MemoryResetRange(thr, /*pc=*/ 4, thr->tls_addr, thr_beg - thr->tls_addr);
|
||||
MemoryResetRange(thr, /*pc=*/ 5,
|
||||
thr_end, thr->tls_addr + thr->tls_size - thr_end);
|
||||
}
|
||||
DontNeedShadowFor(thr->stk_addr, thr->stk_size);
|
||||
if (thr->tls_addr && thr->tls_size)
|
||||
DontNeedShadowFor(thr->tls_addr, thr->tls_size);
|
||||
thr->is_alive = false;
|
||||
Context *ctx = CTX();
|
||||
ctx->thread_registry->FinishThread(thr->tid);
|
||||
|
|
Loading…
Reference in New Issue