diff options
| author | Kamil Rytarowski <n54@gmx.com> | 2017-11-03 20:48:19 +0000 | 
|---|---|---|
| committer | Kamil Rytarowski <n54@gmx.com> | 2017-11-03 20:48:19 +0000 | 
| commit | 55435b74271433e1767bb4f6d192f273862ff698 (patch) | |
| tree | 87171fb7b655ddc002fdbfd4f4cb5bf156abb2be | |
| parent | 0c99007db1b31d5d00c449ad2af2dd9bda051844 (diff) | |
| download | bcm5719-llvm-55435b74271433e1767bb4f6d192f273862ff698.tar.gz bcm5719-llvm-55435b74271433e1767bb4f6d192f273862ff698.zip | |
Correct detection of a thread termination
Summary:
Stop using the Linux solution with pthread_key_create(3).
This approach does not work on NetBSD, because calling
the thread destructor is not the latest operation on a POSIX
thread entity. NetBSD's libpthread still calls at least
pthread_mutex_lock and pthread_mutex_unlock.
Detect _lwp_exit(2) call as it is really the latest operation
called from a detaching POSIX thread.
This resolves one set of crashes observed in
the Thread Sanitizer execution.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, kcc, vitalybuka, dvyukov, eugenis
Reviewed By: vitalybuka
Subscribers: llvm-commits, kubamracek, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D39618
llvm-svn: 317363
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interceptors.cc | 21 | 
1 files changed, 17 insertions, 4 deletions
| diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc index 9fbfef52cdc..db92f7528a0 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc @@ -265,7 +265,7 @@ static ThreadSignalContext *SigCtx(ThreadState *thr) {    return ctx;  } -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD  static unsigned g_thread_finalize_key;  #endif @@ -869,7 +869,7 @@ void DestroyThreadState() {  }  }  // namespace __tsan -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD  static void thread_finalize(void *v) {    uptr iter = (uptr)v;    if (iter > 1) { @@ -899,7 +899,7 @@ extern "C" void *__tsan_thread_start_func(void *arg) {      ThreadState *thr = cur_thread();      // Thread-local state is not initialized yet.      ScopedIgnoreInterceptors ignore; -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD      ThreadIgnoreBegin(thr, 0);      if (pthread_setspecific(g_thread_finalize_key,                              (void *)GetPthreadDestructorIterations())) { @@ -2448,6 +2448,17 @@ TSAN_INTERCEPTOR(void *, __tls_get_addr, void *arg) {  }  #endif +#if SANITIZER_NETBSD +TSAN_INTERCEPTOR(void, _lwp_exit) { +  SCOPED_TSAN_INTERCEPTOR(_lwp_exit); +  REAL(_lwp_exit)(); +  DestroyThreadState(); +} +#define TSAN_MAYBE_INTERCEPT__LWP_EXIT TSAN_INTERCEPT(_lwp_exit) +#else +#define TSAN_MAYBE_INTERCEPT__LWP_EXIT +#endif +  namespace __tsan {  static void finalize(void *arg) { @@ -2616,6 +2627,8 @@ void InitializeInterceptors() {    TSAN_INTERCEPT(__tls_get_addr);  #endif +  TSAN_MAYBE_INTERCEPT__LWP_EXIT; +  #if !SANITIZER_MAC && !SANITIZER_ANDROID    // Need to setup it, because interceptors check that the function is resolved.    // But atexit is emitted directly into the module, so can't be resolved. @@ -2627,7 +2640,7 @@ void InitializeInterceptors() {      Die();    } -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD    if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {      Printf("ThreadSanitizer: failed to create thread key\n");      Die(); | 

