[compiler-rt] r193602 - tsan/asan: support pthread_setname_np to set thread names

Kostya Serebryany kcc at google.com
Wed Nov 13 06:23:28 PST 2013


Also note that this change does not implement general case
of pthread_setname_np for asan, only for tsan.
% clang -fsanitize=address thread_name2.cc  && ./a.out
READ of size 4 at 0x000001ab4e48 thread T1 <<<< no thread name is printed.

That's because the call to asanThreadRegistry().CreateThread in
asan/asan_interceptors.cc
receives some strange first parameter instead of pthread_self() (which does
not exist at this point).

// thread_name2.cc
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

int zzz[10];
volatile int one = 1;

void *Thread1(void *x) {
  // pthread_setname_np(pthread_self(), "foobar1");
  sleep(1);
  zzz[one * 10]++;
  return 0;
}

int main() {
  pthread_t t[1];
  pthread_create(&t[0], 0, Thread1, 0);
  pthread_setname_np(t[0], "foobar1");
  pthread_join(t[0], NULL);
}




On Wed, Nov 13, 2013 at 4:58 PM, Kostya Serebryany <kcc at google.com> wrote:

> This causes a severe performance degradation if a test with lots of
> threads setting their names simultaneously.
> Previously, we did not intercept  pthread_setname_np and relied on prctl
> interceptor.
> Now on every pthread_setname_np we do a mutex lock and O(n_threads)
> operations under a lock.
> Please fix.
>
>
> On Tue, Oct 29, 2013 at 2:30 PM, Dmitry Vyukov <dvyukov at google.com> wrote:
>
>> Author: dvyukov
>> Date: Tue Oct 29 05:30:39 2013
>> New Revision: 193602
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=193602&view=rev
>> Log:
>> tsan/asan: support pthread_setname_np to set thread names
>>
>>
>> Added:
>>     compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc
>> Modified:
>>     compiler-rt/trunk/lib/asan/asan_interceptors.cc
>>     compiler-rt/trunk/lib/msan/msan_interceptors.cc
>>
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
>>
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
>>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc
>>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h
>>     compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
>>     compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
>>     compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
>>
>> Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=193602&r1=193601&r2=193602&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
>> +++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Tue Oct 29 05:30:39
>> 2013
>> @@ -130,6 +130,8 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free,
>>    do {                                                      \
>>    } while (false)
>>  #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)
>> +#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
>> +    asanThreadRegistry().SetThreadNameByUserId(thread, name)
>>  #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
>>  #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
>>  #include "sanitizer_common/sanitizer_common_interceptors.inc"
>>
>> Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=193602&r1=193601&r2=193602&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
>> +++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Tue Oct 29 05:30:39
>> 2013
>> @@ -1224,6 +1224,9 @@ extern "C" int *__errno_location(void);
>>  #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
>>    do {                                                \
>>    } while (false)  // FIXME
>> +#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
>> +  do {                                                         \
>> +  } while (false)  // FIXME
>>  #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
>>  #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
>>  #include "sanitizer_common/sanitizer_common_interceptors.inc"
>>
>> Modified:
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=193602&r1=193601&r2=193602&view=diff
>>
>> ==============================================================================
>> ---
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
>> (original)
>> +++
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
>> Tue Oct 29 05:30:39 2013
>> @@ -23,6 +23,7 @@
>>  //   COMMON_INTERCEPTOR_ON_EXIT
>>  //   COMMON_INTERCEPTOR_MUTEX_LOCK
>>  //   COMMON_INTERCEPTOR_MUTEX_UNLOCK
>> +//   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
>>
>>  //===----------------------------------------------------------------------===//
>>  #include "interception/interception.h"
>>  #include "sanitizer_platform_interceptors.h"
>> @@ -34,19 +35,19 @@
>>  #endif // _WIN32
>>
>>  #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
>> -#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size)
>> +#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) {}
>>  #endif
>>
>>  #ifndef COMMON_INTERCEPTOR_FD_ACCESS
>> -#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd)
>> +#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
>>  #endif
>>
>>  #ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
>> -#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m)
>> +#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
>>  #endif
>>
>>  #ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
>> -#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m)
>> +#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
>>  #endif
>>
>>  #if SANITIZER_INTERCEPT_STRCMP
>> @@ -2655,6 +2656,18 @@ INTERCEPTOR(char *, tempnam, char *dir,
>>  #define INIT_TEMPNAM
>>  #endif
>>
>> +#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
>> +INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
>> +  void *ctx;
>> +  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
>> +  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
>> +  return REAL(pthread_setname_np)(thread, name);
>> +}
>> +#define INIT_PTHREAD_SETNAME_NP INTERCEPT_FUNCTION(pthread_setname_np);
>> +#else
>> +#define INIT_PTHREAD_SETNAME_NP
>> +#endif
>> +
>>
>>  #define SANITIZER_COMMON_INTERCEPTORS_INIT \
>>    INIT_STRCMP;                             \
>> @@ -2757,4 +2770,5 @@ INTERCEPTOR(char *, tempnam, char *dir,
>>    INIT_TMPNAM;                             \
>>    INIT_TMPNAM_R;                           \
>>    INIT_TEMPNAM;                            \
>> +  INIT_PTHREAD_SETNAME_NP;                 \
>>  /**/
>>
>> Modified:
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=193602&r1=193601&r2=193602&view=diff
>>
>> ==============================================================================
>> ---
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
>> (original)
>> +++
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
>> Tue Oct 29 05:30:39 2013
>> @@ -149,5 +149,6 @@
>>
>>  # define SANITIZER_INTERCEPT_PHTREAD_MUTEX SI_NOT_WINDOWS
>>  # define SANITIZER_INTERCEPT_PTHREAD_COND SI_NOT_WINDOWS
>> +# define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP SI_LINUX_NOT_ANDROID
>>
>>  #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
>>
>> Modified:
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc?rev=193602&r1=193601&r2=193602&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc
>> (original)
>> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc
>> Tue Oct 29 05:30:39 2013
>> @@ -200,6 +200,18 @@ void ThreadRegistry::SetThreadName(u32 t
>>    tctx->SetName(name);
>>  }
>>
>> +void ThreadRegistry::SetThreadNameByUserId(uptr user_id, const char
>> *name) {
>> +  BlockingMutexLock l(&mtx_);
>> +  for (u32 tid = 0; tid < n_contexts_; tid++) {
>> +    ThreadContextBase *tctx = threads_[tid];
>> +    if (tctx != 0 && tctx->user_id == user_id &&
>> +        tctx->status != ThreadStatusInvalid) {
>> +      tctx->SetName(name);
>> +      return;
>> +    }
>> +  }
>> +}
>> +
>>  void ThreadRegistry::DetachThread(u32 tid) {
>>    BlockingMutexLock l(&mtx_);
>>    CHECK_LT(tid, n_contexts_);
>>
>> Modified:
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h?rev=193602&r1=193601&r2=193602&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h
>> (original)
>> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h
>> Tue Oct 29 05:30:39 2013
>> @@ -109,6 +109,7 @@ class ThreadRegistry {
>>    ThreadContextBase *FindThreadContextByOsIDLocked(uptr os_id);
>>
>>    void SetThreadName(u32 tid, const char *name);
>> +  void SetThreadNameByUserId(uptr user_id, const char *name);
>>    void DetachThread(u32 tid);
>>    void JoinThread(u32 tid, void *arg);
>>    void FinishThread(u32 tid);
>>
>> Added: compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc?rev=193602&view=auto
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc (added)
>> +++ compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc Tue Oct 29
>> 05:30:39 2013
>> @@ -0,0 +1,32 @@
>> +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s
>> +#include <pthread.h>
>> +#include <stdio.h>
>> +#include <unistd.h>
>> +
>> +int Global;
>> +
>> +void *Thread1(void *x) {
>> +  sleep(1);
>> +  Global++;
>> +  return 0;
>> +}
>> +
>> +void *Thread2(void *x) {
>> +  pthread_setname_np(pthread_self(), "foobar2");
>> +  Global--;
>> +  return 0;
>> +}
>> +
>> +int main() {
>> +  pthread_t t[2];
>> +  pthread_create(&t[0], 0, Thread1, 0);
>> +  pthread_create(&t[1], 0, Thread2, 0);
>> +  pthread_setname_np(t[0], "foobar1");
>> +  pthread_join(t[0], NULL);
>> +  pthread_join(t[1], NULL);
>> +}
>> +
>> +// CHECK: WARNING: ThreadSanitizer: data race
>> +// CHECK:   Thread T1 'foobar1'
>> +// CHECK:   Thread T2 'foobar2'
>> +
>>
>> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=193602&r1=193601&r2=193602&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
>> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Tue Oct 29
>> 05:30:39 2013
>> @@ -1837,38 +1837,54 @@ struct TsanInterceptorContext {
>>  #define COMMON_INTERCEPTOR_UNPOISON_PARAM(ctx, count) \
>>    do {                                                \
>>    } while (false)
>> +
>>  #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size)
>>  \
>>    MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr,
>>   \
>>                      ((TsanInterceptorContext *)ctx)->pc, (uptr)ptr,
>> size, \
>>                      true)
>> +
>>  #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size)
>>     \
>>    MemoryAccessRange(((TsanInterceptorContext *) ctx)->thr,
>>    \
>>                      ((TsanInterceptorContext *) ctx)->pc, (uptr) ptr,
>> size, \
>>                      false)
>> +
>>  #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)      \
>>    SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__);         \
>>    TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
>>    ctx = (void *)&_ctx;                                \
>>    (void) ctx;
>> +
>>  #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
>>    FdAcquire(((TsanInterceptorContext *) ctx)->thr, pc, fd)
>> +
>>  #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
>>    FdRelease(((TsanInterceptorContext *) ctx)->thr, pc, fd)
>> +
>>  #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) \
>>    FdAccess(((TsanInterceptorContext *) ctx)->thr, pc, fd)
>> +
>>  #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
>>    FdSocketAccept(((TsanInterceptorContext *) ctx)->thr, pc, fd, newfd)
>> +
>>  #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
>>    ThreadSetName(((TsanInterceptorContext *) ctx)->thr, name)
>> +
>> +#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
>> +  CTX()->thread_registry->SetThreadNameByUserId(thread, name)
>> +
>>  #define COMMON_INTERCEPTOR_BLOCK_REAL(name) BLOCK_REAL(name)
>> +
>>  #define COMMON_INTERCEPTOR_ON_EXIT(ctx) \
>>    OnExit(((TsanInterceptorContext *) ctx)->thr)
>> +
>>  #define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) \
>>    MutexLock(((TsanInterceptorContext *)ctx)->thr, \
>>              ((TsanInterceptorContext *)ctx)->pc, (uptr)m)
>> +
>>  #define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \
>>    MutexUnlock(((TsanInterceptorContext *)ctx)->thr, \
>>              ((TsanInterceptorContext *)ctx)->pc, (uptr)m)
>> +
>>  #include "sanitizer_common/sanitizer_common_interceptors.inc"
>>
>>  #define TSAN_SYSCALL() \
>>
>> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc?rev=193602&r1=193601&r2=193602&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc (original)
>> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc Tue Oct 29 05:30:39 2013
>> @@ -182,6 +182,7 @@ void StatOutput(u64 *stat) {
>>    name[StatInt_pthread_barrier_wait]     = "  pthread_barrier_wait
>>      ";
>>    name[StatInt_pthread_once]             = "  pthread_once
>>      ";
>>    name[StatInt_pthread_getschedparam]    = "  pthread_getschedparam
>>       ";
>> +  name[StatInt_pthread_setname_np]       = "  pthread_setname_np
>>      ";
>>    name[StatInt_sem_init]                 = "  sem_init
>>      ";
>>    name[StatInt_sem_destroy]              = "  sem_destroy
>>       ";
>>    name[StatInt_sem_wait]                 = "  sem_wait
>>      ";
>>
>> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h?rev=193602&r1=193601&r2=193602&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h (original)
>> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h Tue Oct 29 05:30:39 2013
>> @@ -177,6 +177,7 @@ enum StatType {
>>    StatInt_pthread_barrier_wait,
>>    StatInt_pthread_once,
>>    StatInt_pthread_getschedparam,
>> +  StatInt_pthread_setname_np,
>>    StatInt_sem_init,
>>    StatInt_sem_destroy,
>>    StatInt_sem_wait,
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131113/e054cdd9/attachment.html>


More information about the llvm-commits mailing list