diff --git a/compiler-rt/lib/msan/lit_tests/tls_reuse.cc b/compiler-rt/lib/msan/lit_tests/tls_reuse.cc new file mode 100644 index 000000000000..e1de7e87a1ef --- /dev/null +++ b/compiler-rt/lib/msan/lit_tests/tls_reuse.cc @@ -0,0 +1,26 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t + +// Check that when TLS block is reused between threads, its shadow is cleaned. + +#include +#include + +int __thread x; + +void *ThreadFn(void *) { + if (!x) + printf("zzz\n"); + int y; + int * volatile p = &y; + x = *p; + return 0; +} + +int main(void) { + pthread_t t; + for (int i = 0; i < 100; ++i) { + pthread_create(&t, 0, ThreadFn, 0); + pthread_join(t, 0); + } + return 0; +} diff --git a/compiler-rt/lib/msan/msan.cc b/compiler-rt/lib/msan/msan.cc index ecc7cb82817b..4f8f351f3f64 100644 --- a/compiler-rt/lib/msan/msan.cc +++ b/compiler-rt/lib/msan/msan.cc @@ -173,8 +173,9 @@ void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, SymbolizerScope sym_scope; return stack->Unwind(max_s, pc, bp, 0, 0, request_fast_unwind); } - stack->Unwind(max_s, pc, bp, msan_stack_bounds.stack_top, - msan_stack_bounds.stack_bottom, request_fast_unwind); + uptr stack_bottom = msan_stack_bounds.stack_addr; + uptr stack_top = stack_bottom + msan_stack_bounds.stack_size; + stack->Unwind(max_s, pc, bp, stack_top, stack_bottom, request_fast_unwind); } void PrintWarning(uptr pc, uptr bp) { @@ -324,9 +325,10 @@ void __msan_init() { } Symbolizer::Get()->AddHooks(EnterSymbolizer, ExitSymbolizer); - GetThreadStackTopAndBottom(/* at_initialization */ true, - &msan_stack_bounds.stack_top, - &msan_stack_bounds.stack_bottom); + GetThreadStackAndTls(/* main */ true, &msan_stack_bounds.stack_addr, + &msan_stack_bounds.stack_size, + &msan_stack_bounds.tls_addr, + &msan_stack_bounds.tls_size); VPrintf(1, "MemorySanitizer init done\n"); msan_init_is_running = 0; msan_inited = 1; diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h index a50540b077ba..755dd748322c 100644 --- a/compiler-rt/lib/msan/msan.h +++ b/compiler-rt/lib/msan/msan.h @@ -107,7 +107,8 @@ class ScopedThreadLocalStateBackup { if (&__msan_free_hook) __msan_free_hook(ptr) struct MsanStackBounds { - uptr stack_top, stack_bottom; + uptr stack_addr, stack_size; + uptr tls_addr, tls_size; }; extern THREADLOCAL MsanStackBounds msan_stack_bounds; diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index 5dc12af660eb..11896440969d 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -1070,6 +1070,11 @@ static void thread_finalize(void *v) { return; } MsanAllocatorThreadFinish(); + __msan_unpoison((void *)msan_stack_bounds.stack_addr, + msan_stack_bounds.stack_size); + if (msan_stack_bounds.tls_size) + __msan_unpoison((void *)msan_stack_bounds.tls_addr, + msan_stack_bounds.tls_size); } struct ThreadParam { @@ -1089,9 +1094,10 @@ static void *MsanThreadStartFunc(void *arg) { } atomic_store(&p->done, 1, memory_order_release); - GetThreadStackTopAndBottom(/* at_initialization */ false, - &msan_stack_bounds.stack_top, - &msan_stack_bounds.stack_bottom); + GetThreadStackAndTls(/* main */ false, &msan_stack_bounds.stack_addr, + &msan_stack_bounds.stack_size, + &msan_stack_bounds.tls_addr, + &msan_stack_bounds.tls_size); return callback(param); }