Skip to content

Commit

Permalink
tsan: fix crash during thread exit
Browse files Browse the repository at this point in the history
Use of gethostent provokes caching of some resources inside of libc.
They are freed in __libc_thread_freeres very late in thread lifetime,
after our ThreadFinish. __libc_thread_freeres calls free which
previously crashed in malloc hooks.
Fix it by setting ignore_interceptors for finished threads,
which in turn prevents malloc hooks.

Reviewed By: melver

Differential Revision: https://reviews.llvm.org/D113989
  • Loading branch information
dvyukov committed Nov 16, 2021
1 parent 50acc6d commit c7081b5
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
3 changes: 3 additions & 0 deletions compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ void ThreadFinish(ThreadState *thr) {
DontNeedShadowFor(thr->tls_addr, thr->tls_size);
thr->is_dead = true;
thr->is_inited = false;
#if !SANITIZER_GO
thr->ignore_interceptors++;
#endif
ctx->thread_registry.FinishThread(thr->tid);
}

Expand Down
37 changes: 37 additions & 0 deletions compiler-rt/test/tsan/Linux/sethostent.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s

// Use of gethostent provokes caching of some resources inside of libc.
// They are freed in __libc_thread_freeres very late in thread lifetime,
// after our ThreadFinish. __libc_thread_freeres calls free which
// previously crashed in malloc hooks.

#include "../test.h"
#include <netdb.h>

long X;

extern "C" void __sanitizer_malloc_hook(void *ptr, size_t size) {
__atomic_fetch_add(&X, 1, __ATOMIC_RELAXED);
}

extern "C" void __sanitizer_free_hook(void *ptr) {
__atomic_fetch_sub(&X, 1, __ATOMIC_RELAXED);
}

void *Thread(void *x) {
sethostent(1);
gethostbyname("llvm.org");
gethostent();
endhostent();
return NULL;
}

int main() {
pthread_t th;
pthread_create(&th, NULL, Thread, NULL);
pthread_join(th, NULL);
fprintf(stderr, "DONE\n");
return 0;
}

// CHECK: DONE

0 comments on commit c7081b5

Please sign in to comment.