From: Dmitry Vyukov Date: Tue, 16 Nov 2021 13:29:02 +0000 (+0100) Subject: tsan: fix crash during thread exit X-Git-Tag: upstream/15.0.7~25555 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c7081b5b4cb57f27e6a075e1b5a63b7951cd8a7a;p=platform%2Fupstream%2Fllvm.git tsan: fix crash during thread exit 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 --- diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp index 8532f5d..dfead43 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp @@ -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); } diff --git a/compiler-rt/test/tsan/Linux/sethostent.cpp b/compiler-rt/test/tsan/Linux/sethostent.cpp new file mode 100644 index 0000000..6cb8c29 --- /dev/null +++ b/compiler-rt/test/tsan/Linux/sethostent.cpp @@ -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 + +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