[hwasan] use real TLS on linux to store the current thread -- this way we can call t->Destroy in __hwasan_thread_exit, same as on Android

llvm-svn: 341435
This commit is contained in:
Kostya Serebryany 2018-09-05 00:17:23 +00:00
parent 2b8c69204b
commit 9fbedcad71
1 changed files with 11 additions and 7 deletions

View File

@ -221,7 +221,7 @@ extern "C" void __hwasan_thread_exit() {
Thread *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) CHECK(t);
t->Destroy(); t->Destroy();
} }
@ -229,15 +229,17 @@ extern "C" void __hwasan_thread_exit() {
static pthread_key_t tsd_key; static pthread_key_t tsd_key;
static bool tsd_key_inited = false; static bool tsd_key_inited = false;
static THREADLOCAL Thread *current_thread;
void HwasanTSDDtor(void *tsd) { void HwasanTSDDtor(void *tsd) {
Thread *t = (Thread*)tsd; Thread *t = current_thread;
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, (void*)1));
return; return;
} }
t->Destroy();
__hwasan_thread_exit(); __hwasan_thread_exit();
current_thread = nullptr;
} }
void HwasanTSDInit() { void HwasanTSDInit() {
@ -247,15 +249,17 @@ void HwasanTSDInit() {
} }
Thread *GetCurrentThread() { Thread *GetCurrentThread() {
return (Thread *)pthread_getspecific(tsd_key); return current_thread;
} }
void SetCurrentThread(Thread *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 Thread. // Make sure we do not reset the current Thread.
CHECK_EQ(current_thread, nullptr);
current_thread = t;
CHECK_EQ(0, pthread_getspecific(tsd_key)); CHECK_EQ(0, pthread_getspecific(tsd_key));
pthread_setspecific(tsd_key, (void *)t); CHECK_EQ(0, pthread_setspecific(tsd_key, (void *)1));
} }
#elif SANITIZER_ANDROID #elif SANITIZER_ANDROID
void HwasanTSDInit() {} void HwasanTSDInit() {}