From 14ed39ad6ec1fc0d1d16583b8070b4ec064f0680 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Fri, 21 Apr 2017 14:00:23 -0700 Subject: [PATCH] [v9_10] give threads unique names to assist debugging 4602. [func] Threads are now set to human-readable names to assist debugging, when supported by the OS. [RT #43234] (cherry picked from commit d26ae7fc0802f67a50f6f01152f356182d47305e) (cherry picked from commit 8b9c4592ed718c4187971f1104381faf538bf4f7) --- CHANGES | 4 ++++ config.h.in | 9 +++++++++ configure | 26 ++++++++++++++++++++++++++ configure.in | 4 ++++ doc/arm/notes.xml | 7 ++++++- lib/isc/nothreads/include/isc/thread.h | 3 +++ lib/isc/nothreads/thread.c | 5 +++++ lib/isc/pthreads/include/isc/thread.h | 7 +++++++ lib/isc/pthreads/thread.c | 16 ++++++++++++++++ lib/isc/task.c | 4 ++++ lib/isc/timer.c | 1 + lib/isc/unix/socket.c | 1 + lib/isc/win32/include/isc/thread.h | 3 +++ lib/isc/win32/libisc.def.in | 1 + lib/isc/win32/thread.c | 6 ++++++ 15 files changed, 96 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 3283df5723..e94ce0eca1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +4602. [func] Threads are now set to human-readable + names to assist debugging, when supported by + the OS. [RT #43234] + 4601. [bug] Reject incorrect RSA key lengths during key generation and and sign/verify context creation. [RT #45043] diff --git a/config.h.in b/config.h.in index 9542ed92dd..bf7f385893 100644 --- a/config.h.in +++ b/config.h.in @@ -387,6 +387,15 @@ int sigwait(const unsigned int *set, int *sig); /* Support for PTHREAD_MUTEX_ADAPTIVE_NP */ #undef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP +/* Define to 1 if you have the header file. */ +#undef HAVE_PTHREAD_NP_H + +/* Define to 1 if you have the `pthread_setname_np' function. */ +#undef HAVE_PTHREAD_SETNAME_NP + +/* Define to 1 if you have the `pthread_set_name_np' function. */ +#undef HAVE_PTHREAD_SET_NAME_NP + /* Define to 1 if you have the `pthread_yield' function. */ #undef HAVE_PTHREAD_YIELD diff --git a/configure b/configure index ad0cc7c9fe..6a89356c94 100755 --- a/configure +++ b/configure @@ -15611,6 +15611,32 @@ fi ;; esac + # Look for functions relating to thread naming + for ac_func in pthread_setname_np pthread_set_name_np +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + for ac_header in pthread_np.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "pthread_np.h" "ac_cv_header_pthread_np_h" "$ac_includes_default" +if test "x$ac_cv_header_pthread_np_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PTHREAD_NP_H 1 +_ACEOF + +fi + +done + + # # Look for sysconf to allow detection of the number of processors. # diff --git a/configure.in b/configure.in index 93e3582327..df08e692cc 100644 --- a/configure.in +++ b/configure.in @@ -1344,6 +1344,10 @@ then ;; esac + # Look for functions relating to thread naming + AC_CHECK_FUNCS(pthread_setname_np pthread_set_name_np) + AC_CHECK_HEADERS(pthread_np.h) + # # Look for sysconf to allow detection of the number of processors. # diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index ec4d94bdd7..43136db591 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -81,7 +81,12 @@ - None. + Threads in named are now set to human-readable + names to assist debugging on operating systems that support that. + Threads will have names such as "isc-timer", "isc-sockmgr", + "isc-worker0001", and so on. This will affect the reporting of + subsidiary thread names in ps and + top, but not the main thread. [RT #43234] diff --git a/lib/isc/nothreads/include/isc/thread.h b/lib/isc/nothreads/include/isc/thread.h index fee57005b6..8aa63172f6 100644 --- a/lib/isc/nothreads/include/isc/thread.h +++ b/lib/isc/nothreads/include/isc/thread.h @@ -28,6 +28,9 @@ ISC_LANG_BEGINDECLS void isc_thread_setconcurrency(unsigned int level); +void +isc_thread_setname(isc_thread_t, const char *); + #define isc_thread_self() ((unsigned long)0) #define isc_thread_yield() ((void)0) diff --git a/lib/isc/nothreads/thread.c b/lib/isc/nothreads/thread.c index 9075e25513..f4f845701a 100644 --- a/lib/isc/nothreads/thread.c +++ b/lib/isc/nothreads/thread.c @@ -26,3 +26,8 @@ void isc_thread_setconcurrency(unsigned int level) { UNUSED(level); } + +void isc_thread_setname(isc_thread_t thread, const char *name) { + UNUSED(thread); + UNUSED(name); +} diff --git a/lib/isc/pthreads/include/isc/thread.h b/lib/isc/pthreads/include/isc/thread.h index 47648830e9..86473e435b 100644 --- a/lib/isc/pthreads/include/isc/thread.h +++ b/lib/isc/pthreads/include/isc/thread.h @@ -24,6 +24,10 @@ #include +#if defined(HAVE_PTHREAD_NP_H) +#include +#endif + #include #include @@ -44,6 +48,9 @@ isc_thread_setconcurrency(unsigned int level); void isc_thread_yield(void); +void +isc_thread_setname(isc_thread_t, const char *); + /* XXX We could do fancier error handling... */ #define isc_thread_join(t, rp) \ diff --git a/lib/isc/pthreads/thread.c b/lib/isc/pthreads/thread.c index 97821a2cad..85e5444234 100644 --- a/lib/isc/pthreads/thread.c +++ b/lib/isc/pthreads/thread.c @@ -79,6 +79,22 @@ isc_thread_setconcurrency(unsigned int level) { #endif } +void +isc_thread_setname(isc_thread_t thread, const char *name) { +#if defined(HAVE_PTHREAD_SETNAME_NP) && defined(_GNU_SOURCE) + /* + * macOS has pthread_setname_np but only works on the + * current thread so it's not used here + */ + (void)pthread_setname_np(thread, name); +#elif defined(HAVE_PTHREAD_SET_NAME_NP) + (void)pthread_set_name_np(thread, name); +#else + UNUSED(thread); + UNUSED(name); +#endif +} + void isc_thread_yield(void) { #if defined(HAVE_SCHED_YIELD) diff --git a/lib/isc/task.c b/lib/isc/task.c index 44da80c677..9a627c241a 100644 --- a/lib/isc/task.c +++ b/lib/isc/task.c @@ -1438,6 +1438,10 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers, if (isc_thread_create(run, manager, &manager->threads[manager->workers]) == ISC_R_SUCCESS) { + char name[16]; /* thread name limit on Linux */ + snprintf(name, sizeof(name), "isc-worker%04d", i); + isc_thread_setname(manager->threads[manager->workers], + name); manager->workers++; started++; } diff --git a/lib/isc/timer.c b/lib/isc/timer.c index 7e6242794a..7e466d0ac2 100644 --- a/lib/isc/timer.c +++ b/lib/isc/timer.c @@ -923,6 +923,7 @@ isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { ISC_MSG_FAILED, "failed")); return (ISC_R_UNEXPECTED); } + isc_thread_setname(manager->thread, "isc-timer"); #endif #ifdef USE_SHARED_MANAGER manager->refs = 1; diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index 3e8c95aecb..259eef823a 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -4755,6 +4755,7 @@ isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, result = ISC_R_UNEXPECTED; goto cleanup; } + isc_thread_setname(manager->watcher, "isc-socket"); #endif /* USE_WATCHER_THREAD */ isc_mem_attach(mctx, &manager->mctx); diff --git a/lib/isc/win32/include/isc/thread.h b/lib/isc/win32/include/isc/thread.h index bfe860b659..3de056aa0d 100644 --- a/lib/isc/win32/include/isc/thread.h +++ b/lib/isc/win32/include/isc/thread.h @@ -83,6 +83,9 @@ isc_thread_join(isc_thread_t, isc_threadresult_t *); void isc_thread_setconcurrency(unsigned int level); +void +isc_thread_setname(isc_thread_t, const char *); + int isc_thread_key_create(isc_thread_key_t *key, void (*func)(void *)); diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index ce8567a357..0ff9430cf0 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -668,6 +668,7 @@ isc_thread_key_delete isc_thread_key_getspecific isc_thread_key_setspecific isc_thread_setconcurrency +isc_thread_setname isc_time_add isc_time_compare isc_time_formatISO8601 diff --git a/lib/isc/win32/thread.c b/lib/isc/win32/thread.c index be955ea25c..7e717ca4a0 100644 --- a/lib/isc/win32/thread.c +++ b/lib/isc/win32/thread.c @@ -67,6 +67,12 @@ isc_thread_setconcurrency(unsigned int level) { */ } +void +isc_thread_setname(isc_thread_t thread, const char *name) { + UNUSED(thread); + UNUSED(name); +} + void * isc_thread_key_getspecific(isc_thread_key_t key) { return(TlsGetValue(key));