Add common util to set thread name
authorMichael Jeanson <mjeanson@efficios.com>
Wed, 12 Aug 2020 21:08:07 +0000 (17:08 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 26 Aug 2020 17:01:02 +0000 (13:01 -0400)
Use the same code to set all the thread names and fail gracefully on
platforms that don't support them.

This sets the minimum requirement for thread names on Linux to Glibc
>= 2.12, which seems reasonable.

Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I61c0b9adb6c2309fed91b5a1b11ebc5ee2a637ce

configure.ac
m4/lttng_pthread_setname_np.m4 [new file with mode: 0644]
src/common/Makefile.am
src/common/compat/Makefile.am
src/common/compat/prctl.h [deleted file]
src/common/compat/pthread.h [new file with mode: 0644]
src/common/error.c
src/common/runas.c
src/common/thread.c [new file with mode: 0644]
src/common/thread.h [new file with mode: 0644]

index c6b83b78aeadf0f09b8ca1b840363b3cb4f7b824..dd0fb21da1288236db199e460af6f25432343da1 100644 (file)
@@ -237,6 +237,9 @@ AC_CHECK_FUNCS([ \
        sched_getcpu sysconf sync_file_range
 ])
 
        sched_getcpu sysconf sync_file_range
 ])
 
+# Check for pthread_setname_np and its signature
+LTTNG_PTHREAD_SETNAME_NP
+
 # Check if clock_gettime, timer_create, timer_settime, and timer_delete are available in lib rt, and if so,
 # add -lrt to LIBS
 AC_CHECK_LIB([rt], [clock_gettime, timer_create, timer_settime, timer_delete])
 # Check if clock_gettime, timer_create, timer_settime, and timer_delete are available in lib rt, and if so,
 # add -lrt to LIBS
 AC_CHECK_LIB([rt], [clock_gettime, timer_create, timer_settime, timer_delete])
diff --git a/m4/lttng_pthread_setname_np.m4 b/m4/lttng_pthread_setname_np.m4
new file mode 100644 (file)
index 0000000..a8526e8
--- /dev/null
@@ -0,0 +1,70 @@
+# SYNOPSIS
+#
+#   LTTNG_PTHREAD_SETNAME_NP
+#
+# LICENSE
+#
+#   Copyright (c) 2020 Michael Jeanson <mjeanson@efficios.com>
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 2 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([LTTNG_PTHREAD_SETNAME_NP], [
+AC_REQUIRE([AX_PTHREAD])
+AC_LANG_PUSH([C])
+
+lttng_pthread_setname_np_save_LDFLAGS="$LDFLAGS"
+lttng_pthread_setname_np_save_LIBS="$LIBS"
+LDFLAGS="$LDFLAGS $PTHREAD_CFLAGS"
+LIBS="$LIBS $PTHREAD_LIBS"
+
+# GLIBC >= 2.12, Solaris >= 11.3
+AC_MSG_CHECKING(for pthread_setname_np(pthread_t, const char*))
+AC_LINK_IFELSE(
+    [AC_LANG_PROGRAM(
+        [#include <pthread.h>],
+        [pthread_setname_np(pthread_self(), "example")])],
+    [AC_MSG_RESULT(yes)
+     AC_DEFINE(HAVE_PTHREAD_SETNAME_NP_WITH_TID,1,
+        [Have function pthread_setname_np(pthread_t, const char*)])],
+    [AC_MSG_RESULT(no)])
+
+# MacOS X >= 10.6, iOS >= 3.2
+AC_MSG_CHECKING(for pthread_setname_np(const char*))
+AC_LINK_IFELSE(
+    [AC_LANG_PROGRAM(
+        [#include <pthread.h>],
+        [pthread_setname_np("example")])],
+    [AC_MSG_RESULT(yes)
+     AC_DEFINE(HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID,1,
+        [Have function pthread_setname_np(const char*)])],
+    [AC_MSG_RESULT(no)])
+
+LDFLAGS=$lttng_pthread_setname_np_save_LDFLAGS
+LIBS=$lttng_pthread_setname_np_save_LIBS
+
+AC_LANG_POP
+])dnl LTTNG_PTHREAD_SETNAME_NP
index 6a841e92a703bc82d4f85b73ba228e44dd383157..6ee43e48f5913fe48bc8237a8d95fa3f49ce7492 100644 (file)
@@ -75,6 +75,7 @@ libcommon_la_SOURCES = \
        userspace-probe.c \
        utils.c utils.h \
        uuid.c uuid.h \
        userspace-probe.c \
        utils.c utils.h \
        uuid.c uuid.h \
+       thread.c thread.h \
        tracker.c tracker.h \
        waiter.c waiter.h
 
        tracker.c tracker.h \
        waiter.c waiter.h
 
index 2430fceab5d3b8ce1eb33c0015c63535bba75e67..0878b00c25c348239b38366e83df9de2517b7ffa 100644 (file)
@@ -10,5 +10,5 @@ endif
 
 libcompat_la_SOURCES = poll.h fcntl.h endian.h mman.h dirent.h \
                socket.h compat-fcntl.c tid.h \
 
 libcompat_la_SOURCES = poll.h fcntl.h endian.h mman.h dirent.h \
                socket.h compat-fcntl.c tid.h \
-               getenv.h string.h prctl.h paths.h netdb.h $(COMPAT) \
+               getenv.h string.h paths.h pthread.h netdb.h $(COMPAT) \
                time.h directory-handle.h directory-handle.c path.h
                time.h directory-handle.h directory-handle.c path.h
diff --git a/src/common/compat/prctl.h b/src/common/compat/prctl.h
deleted file mode 100644 (file)
index 197b393..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * SPDX-License-Identifier: GPL-2.0-only
- *
- */
-
-#ifndef _COMPAT_PRCTL_H
-#define _COMPAT_PRCTL_H
-
-#ifdef __linux__
-#include <sys/prctl.h>
-
-static inline
-int lttng_prctl(int option, unsigned long arg2, unsigned long arg3,
-               unsigned long arg4, unsigned long arg5)
-{
-       return prctl(option, arg2, arg3, arg4, arg5);
-}
-
-#else
-
-#ifndef PR_SET_NAME
-#define PR_SET_NAME 0
-#endif /* PR_SET_NAME */
-
-static inline
-int lttng_prctl(int option, unsigned long arg2, unsigned long arg3,
-               unsigned long arg4, unsigned long arg5)
-{
-       return -ENOSYS;
-}
-
-#endif /* __linux__ */
-
-#endif /* _COMPAT_PRCTL_H */
diff --git a/src/common/compat/pthread.h b/src/common/compat/pthread.h
new file mode 100644 (file)
index 0000000..a5f91b3
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+#ifndef _COMPAT_PTHREAD_H
+#define _COMPAT_PTHREAD_H
+
+#include <pthread.h>
+
+#if defined(HAVE_PTHREAD_SETNAME_NP_WITH_TID)
+static inline
+int lttng_pthread_setname_np(const char *name)
+{
+       return pthread_setname_np(pthread_self(), name);
+}
+#elif defined(HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID)
+static inline
+int lttng_pthread_setname_np(const char *name)
+{
+       return pthread_setname_np(name);
+}
+#else
+/*
+ * For platforms without thread name support, do nothing.
+ */
+static inline
+int lttng_pthread_setname_np(const char *name)
+{
+       return -ENOSYS;
+}
+#endif
+
+#endif /* _COMPAT_PTHREAD_H */
index 82190b9fd527cea831f61e9620b43f73d1984c17..11dbc90289806decc6507f11f94727ab9e0476a1 100644 (file)
@@ -14,6 +14,7 @@
 #include <string.h>
 
 #include <common/common.h>
 #include <string.h>
 
 #include <common/common.h>
+#include <common/thread.h>
 #include <common/compat/getenv.h>
 #include <lttng/lttng-error.h>
 
 #include <common/compat/getenv.h>
 #include <lttng/lttng-error.h>
 
@@ -77,16 +78,9 @@ void logger_set_thread_name(const char *name, bool set_pthread_name)
        URCU_TLS(logger_thread_name) = name;
 
        if (set_pthread_name) {
        URCU_TLS(logger_thread_name) = name;
 
        if (set_pthread_name) {
-               char pthread_name[16];
-
-               /*
-                * Truncations are expected since pthread limits thread names to
-                * a generous 16 characters.
-                */
-               strncpy(pthread_name, name, sizeof(pthread_name));
-               pthread_name[sizeof(pthread_name) - 1] = '\0';
-               ret = pthread_setname_np(pthread_self(), pthread_name);
-               if (ret) {
+               ret = lttng_thread_setname(name);
+               if (ret && ret != -ENOSYS) {
+                       /* Don't fail as this is not essential. */
                        DBG("Failed to set pthread name attribute");
                }
        }
                        DBG("Failed to set pthread name attribute");
                }
        }
index 28bcff30a5c550ba7800f2b74aa249362d0c24ec..b1a4b4836a63324b246940fb02f2727a1be90c05 100644 (file)
 #include <common/common.h>
 #include <common/utils.h>
 #include <common/compat/getenv.h>
 #include <common/common.h>
 #include <common/utils.h>
 #include <common/compat/getenv.h>
-#include <common/compat/prctl.h>
 #include <common/unix.h>
 #include <common/defaults.h>
 #include <common/lttng-elf.h>
 #include <common/unix.h>
 #include <common/defaults.h>
 #include <common/lttng-elf.h>
+#include <common/thread.h>
 
 #include <lttng/constant.h>
 
 
 #include <lttng/constant.h>
 
@@ -958,11 +958,10 @@ int run_as_worker(struct run_as_worker *worker)
        memset(worker->procname, 0, proc_orig_len);
        strncpy(worker->procname, DEFAULT_RUN_AS_WORKER_NAME, proc_orig_len);
 
        memset(worker->procname, 0, proc_orig_len);
        strncpy(worker->procname, DEFAULT_RUN_AS_WORKER_NAME, proc_orig_len);
 
-       ret = lttng_prctl(PR_SET_NAME,
-                       (unsigned long) DEFAULT_RUN_AS_WORKER_NAME, 0, 0, 0);
+       ret = lttng_thread_setname(DEFAULT_RUN_AS_WORKER_NAME);
        if (ret && ret != -ENOSYS) {
                /* Don't fail as this is not essential. */
        if (ret && ret != -ENOSYS) {
                /* Don't fail as this is not essential. */
-               PERROR("prctl PR_SET_NAME");
+               DBG("Failed to set pthread name attribute");
        }
 
        memset(&sendret, 0, sizeof(sendret));
        }
 
        memset(&sendret, 0, sizeof(sendret));
diff --git a/src/common/thread.c b/src/common/thread.c
new file mode 100644 (file)
index 0000000..bbcc152
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#include <string.h>
+
+#include <common/compat/pthread.h>
+#include "thread.h"
+
+#define LTTNG_PTHREAD_NAMELEN 16
+
+int lttng_thread_setname(const char *name)
+{
+       int ret;
+       char pthread_name[LTTNG_PTHREAD_NAMELEN];
+
+       /*
+        * Truncations are expected since pthread limits thread names to
+        * a generous 16 characters.
+        */
+       strncpy(pthread_name, name, sizeof(pthread_name));
+       pthread_name[sizeof(pthread_name) - 1] = '\0';
+
+       ret = lttng_pthread_setname_np(pthread_name);
+
+       return ret;
+}
+
diff --git a/src/common/thread.h b/src/common/thread.h
new file mode 100644 (file)
index 0000000..b731722
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2020 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_THREAD_H
+#define LTTNG_THREAD_H
+
+#include <common/macros.h>
+
+/*
+ * Set the current thread name on platforms that support it. The name can
+ * be of arbitrary length and will be truncated to the platform limit,
+ * usually 16.
+ */
+LTTNG_HIDDEN
+int lttng_thread_setname(const char *name);
+
+#endif /* LTTNG_THREAD_H */
This page took 0.031669 seconds and 5 git commands to generate.