[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