<div dir="ltr">Also note that this change does not implement general case of pthread_setname_np for asan, only for tsan.<div>% clang -fsanitize=address thread_name2.cc && ./a.out<br></div><div><div>READ of size 4 at 0x000001ab4e48 thread T1 <<<< no thread name is printed.<br>
</div><div><br></div><div>That's because the call to asanThreadRegistry().CreateThread in asan/asan_interceptors.cc</div><div>receives some strange first parameter instead of pthread_self() (which does not exist at this point). </div>
<div><br></div><div>// thread_name2.cc</div><div>#include <pthread.h></div><div>#include <stdio.h></div><div>#include <unistd.h></div><div><br></div><div>int zzz[10];</div><div>volatile int one = 1;</div>
<div><br></div><div>void *Thread1(void *x) {</div><div> // pthread_setname_np(pthread_self(), "foobar1");</div><div> sleep(1);</div><div> zzz[one * 10]++;</div><div> return 0;</div><div>}</div><div><br></div>
<div>int main() {</div><div> pthread_t t[1];</div><div> pthread_create(&t[0], 0, Thread1, 0);</div><div> pthread_setname_np(t[0], "foobar1");</div><div> pthread_join(t[0], NULL);</div><div>}</div><div><br>
</div><div><br></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 13, 2013 at 4:58 PM, Kostya Serebryany <span dir="ltr"><<a href="mailto:kcc@google.com" target="_blank">kcc@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">This causes a severe performance degradation if a test with lots of threads setting their names simultaneously. <div>
Previously, we did not intercept <span style="font-family:arial,sans-serif;font-size:13px">pthread_setname_np and relied on prctl interceptor. </span></div>
<div><span style="font-family:arial,sans-serif;font-size:13px">Now on every </span><span style="font-family:arial,sans-serif;font-size:13px">pthread_setname_np we do a mutex lock and O(n_threads) operations under a lock.</span></div>
<div><span style="font-family:arial,sans-serif;font-size:13px">Please fix. </span></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Oct 29, 2013 at 2:30 PM, Dmitry Vyukov <span dir="ltr"><<a href="mailto:dvyukov@google.com" target="_blank">dvyukov@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dvyukov<br>
Date: Tue Oct 29 05:30:39 2013<br>
New Revision: 193602<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=193602&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=193602&view=rev</a><br>
Log:<br>
tsan/asan: support pthread_setname_np to set thread names<br>
<br>
<br>
Added:<br>
compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc<br>
Modified:<br>
compiler-rt/trunk/lib/asan/asan_interceptors.cc<br>
compiler-rt/trunk/lib/msan/msan_interceptors.cc<br>
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc<br>
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h<br>
compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc<br>
compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h<br>
<br>
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=193602&r1=193601&r2=193602&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=193602&r1=193601&r2=193602&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)<br>
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Tue Oct 29 05:30:39 2013<br>
@@ -130,6 +130,8 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free,<br>
do { \<br>
} while (false)<br>
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)<br>
+#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \<br>
+ asanThreadRegistry().SetThreadNameByUserId(thread, name)<br>
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)<br>
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()<br>
#include "sanitizer_common/sanitizer_common_interceptors.inc"<br>
<br>
Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=193602&r1=193601&r2=193602&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=193602&r1=193601&r2=193602&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)<br>
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Tue Oct 29 05:30:39 2013<br>
@@ -1224,6 +1224,9 @@ extern "C" int *__errno_location(void);<br>
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \<br>
do { \<br>
} while (false) // FIXME<br>
+#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \<br>
+ do { \<br>
+ } while (false) // FIXME<br>
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)<br>
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()<br>
#include "sanitizer_common/sanitizer_common_interceptors.inc"<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=193602&r1=193601&r2=193602&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=193602&r1=193601&r2=193602&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Tue Oct 29 05:30:39 2013<br>
@@ -23,6 +23,7 @@<br>
// COMMON_INTERCEPTOR_ON_EXIT<br>
// COMMON_INTERCEPTOR_MUTEX_LOCK<br>
// COMMON_INTERCEPTOR_MUTEX_UNLOCK<br>
+// COMMON_INTERCEPTOR_SET_PTHREAD_NAME<br>
//===----------------------------------------------------------------------===//<br>
#include "interception/interception.h"<br>
#include "sanitizer_platform_interceptors.h"<br>
@@ -34,19 +35,19 @@<br>
#endif // _WIN32<br>
<br>
#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE<br>
-#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size)<br>
+#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) {}<br>
#endif<br>
<br>
#ifndef COMMON_INTERCEPTOR_FD_ACCESS<br>
-#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd)<br>
+#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}<br>
#endif<br>
<br>
#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK<br>
-#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m)<br>
+#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}<br>
#endif<br>
<br>
#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK<br>
-#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m)<br>
+#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}<br>
#endif<br>
<br>
#if SANITIZER_INTERCEPT_STRCMP<br>
@@ -2655,6 +2656,18 @@ INTERCEPTOR(char *, tempnam, char *dir,<br>
#define INIT_TEMPNAM<br>
#endif<br>
<br>
+#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP<br>
+INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {<br>
+ void *ctx;<br>
+ COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);<br>
+ COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);<br>
+ return REAL(pthread_setname_np)(thread, name);<br>
+}<br>
+#define INIT_PTHREAD_SETNAME_NP INTERCEPT_FUNCTION(pthread_setname_np);<br>
+#else<br>
+#define INIT_PTHREAD_SETNAME_NP<br>
+#endif<br>
+<br>
<br>
#define SANITIZER_COMMON_INTERCEPTORS_INIT \<br>
INIT_STRCMP; \<br>
@@ -2757,4 +2770,5 @@ INTERCEPTOR(char *, tempnam, char *dir,<br>
INIT_TMPNAM; \<br>
INIT_TMPNAM_R; \<br>
INIT_TEMPNAM; \<br>
+ INIT_PTHREAD_SETNAME_NP; \<br>
/**/<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=193602&r1=193601&r2=193602&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=193602&r1=193601&r2=193602&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Tue Oct 29 05:30:39 2013<br>
@@ -149,5 +149,6 @@<br>
<br>
# define SANITIZER_INTERCEPT_PHTREAD_MUTEX SI_NOT_WINDOWS<br>
# define SANITIZER_INTERCEPT_PTHREAD_COND SI_NOT_WINDOWS<br>
+# define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP SI_LINUX_NOT_ANDROID<br>
<br>
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc?rev=193602&r1=193601&r2=193602&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc?rev=193602&r1=193601&r2=193602&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc Tue Oct 29 05:30:39 2013<br>
@@ -200,6 +200,18 @@ void ThreadRegistry::SetThreadName(u32 t<br>
tctx->SetName(name);<br>
}<br>
<br>
+void ThreadRegistry::SetThreadNameByUserId(uptr user_id, const char *name) {<br>
+ BlockingMutexLock l(&mtx_);<br>
+ for (u32 tid = 0; tid < n_contexts_; tid++) {<br>
+ ThreadContextBase *tctx = threads_[tid];<br>
+ if (tctx != 0 && tctx->user_id == user_id &&<br>
+ tctx->status != ThreadStatusInvalid) {<br>
+ tctx->SetName(name);<br>
+ return;<br>
+ }<br>
+ }<br>
+}<br>
+<br>
void ThreadRegistry::DetachThread(u32 tid) {<br>
BlockingMutexLock l(&mtx_);<br>
CHECK_LT(tid, n_contexts_);<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h?rev=193602&r1=193601&r2=193602&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h?rev=193602&r1=193601&r2=193602&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h Tue Oct 29 05:30:39 2013<br>
@@ -109,6 +109,7 @@ class ThreadRegistry {<br>
ThreadContextBase *FindThreadContextByOsIDLocked(uptr os_id);<br>
<br>
void SetThreadName(u32 tid, const char *name);<br>
+ void SetThreadNameByUserId(uptr user_id, const char *name);<br>
void DetachThread(u32 tid);<br>
void JoinThread(u32 tid, void *arg);<br>
void FinishThread(u32 tid);<br>
<br>
Added: compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc?rev=193602&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc?rev=193602&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc (added)<br>
+++ compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc Tue Oct 29 05:30:39 2013<br>
@@ -0,0 +1,32 @@<br>
+// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s<br>
+#include <pthread.h><br>
+#include <stdio.h><br>
+#include <unistd.h><br>
+<br>
+int Global;<br>
+<br>
+void *Thread1(void *x) {<br>
+ sleep(1);<br>
+ Global++;<br>
+ return 0;<br>
+}<br>
+<br>
+void *Thread2(void *x) {<br>
+ pthread_setname_np(pthread_self(), "foobar2");<br>
+ Global--;<br>
+ return 0;<br>
+}<br>
+<br>
+int main() {<br>
+ pthread_t t[2];<br>
+ pthread_create(&t[0], 0, Thread1, 0);<br>
+ pthread_create(&t[1], 0, Thread2, 0);<br>
+ pthread_setname_np(t[0], "foobar1");<br>
+ pthread_join(t[0], NULL);<br>
+ pthread_join(t[1], NULL);<br>
+}<br>
+<br>
+// CHECK: WARNING: ThreadSanitizer: data race<br>
+// CHECK: Thread T1 'foobar1'<br>
+// CHECK: Thread T2 'foobar2'<br>
+<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=193602&r1=193601&r2=193602&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=193602&r1=193601&r2=193602&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Tue Oct 29 05:30:39 2013<br>
@@ -1837,38 +1837,54 @@ struct TsanInterceptorContext {<br>
#define COMMON_INTERCEPTOR_UNPOISON_PARAM(ctx, count) \<br>
do { \<br>
} while (false)<br>
+<br>
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \<br>
MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr, \<br>
((TsanInterceptorContext *)ctx)->pc, (uptr)ptr, size, \<br>
true)<br>
+<br>
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \<br>
MemoryAccessRange(((TsanInterceptorContext *) ctx)->thr, \<br>
((TsanInterceptorContext *) ctx)->pc, (uptr) ptr, size, \<br>
false)<br>
+<br>
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \<br>
SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__); \<br>
TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \<br>
ctx = (void *)&_ctx; \<br>
(void) ctx;<br>
+<br>
#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \<br>
FdAcquire(((TsanInterceptorContext *) ctx)->thr, pc, fd)<br>
+<br>
#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \<br>
FdRelease(((TsanInterceptorContext *) ctx)->thr, pc, fd)<br>
+<br>
#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) \<br>
FdAccess(((TsanInterceptorContext *) ctx)->thr, pc, fd)<br>
+<br>
#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \<br>
FdSocketAccept(((TsanInterceptorContext *) ctx)->thr, pc, fd, newfd)<br>
+<br>
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \<br>
ThreadSetName(((TsanInterceptorContext *) ctx)->thr, name)<br>
+<br>
+#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \<br>
+ CTX()->thread_registry->SetThreadNameByUserId(thread, name)<br>
+<br>
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) BLOCK_REAL(name)<br>
+<br>
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) \<br>
OnExit(((TsanInterceptorContext *) ctx)->thr)<br>
+<br>
#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) \<br>
MutexLock(((TsanInterceptorContext *)ctx)->thr, \<br>
((TsanInterceptorContext *)ctx)->pc, (uptr)m)<br>
+<br>
#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \<br>
MutexUnlock(((TsanInterceptorContext *)ctx)->thr, \<br>
((TsanInterceptorContext *)ctx)->pc, (uptr)m)<br>
+<br>
#include "sanitizer_common/sanitizer_common_interceptors.inc"<br>
<br>
#define TSAN_SYSCALL() \<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc?rev=193602&r1=193601&r2=193602&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc?rev=193602&r1=193601&r2=193602&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc Tue Oct 29 05:30:39 2013<br>
@@ -182,6 +182,7 @@ void StatOutput(u64 *stat) {<br>
name[StatInt_pthread_barrier_wait] = " pthread_barrier_wait ";<br>
name[StatInt_pthread_once] = " pthread_once ";<br>
name[StatInt_pthread_getschedparam] = " pthread_getschedparam ";<br>
+ name[StatInt_pthread_setname_np] = " pthread_setname_np ";<br>
name[StatInt_sem_init] = " sem_init ";<br>
name[StatInt_sem_destroy] = " sem_destroy ";<br>
name[StatInt_sem_wait] = " sem_wait ";<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h?rev=193602&r1=193601&r2=193602&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h?rev=193602&r1=193601&r2=193602&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h Tue Oct 29 05:30:39 2013<br>
@@ -177,6 +177,7 @@ enum StatType {<br>
StatInt_pthread_barrier_wait,<br>
StatInt_pthread_once,<br>
StatInt_pthread_getschedparam,<br>
+ StatInt_pthread_setname_np,<br>
StatInt_sem_init,<br>
StatInt_sem_destroy,<br>
StatInt_sem_wait,<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>