aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Norris <robn@despairlabs.com>2024-04-21 11:43:53 +0000
committerBrian Behlendorf <behlendorf1@llnl.gov>2024-05-01 17:51:49 +0000
commit394800200e033f3a21dcbbf38a1e71b9d33b3b70 (patch)
treeae4650af7452a87003ce7b9dacd667b4c44db666
parent4429ad9276cea193bb29463a7d6c38367d0d78ce (diff)
downloadsrc-394800200e033f3a21dcbbf38a1e71b9d33b3b70.tar.gz
src-394800200e033f3a21dcbbf38a1e71b9d33b3b70.zip
libspl/assert: show process/task details in assert output
Makes it much easier to see what thing complained. Getting thread id, program name and thread name vary wildly between Linux and FreeBSD, so those are set up in macros. pthread_getname_np() did not appear in musl until very recently, but the same info has always been available via prctl(PR_GET_NAME), so we use that instead. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <robn@despairlabs.com> Sponsored-by: https://despairlabs.com/sponsor/ Closes #16140
-rw-r--r--config/user.m42
-rw-r--r--lib/libspl/assert.c36
2 files changed, 35 insertions, 3 deletions
diff --git a/config/user.m4 b/config/user.m4
index 87df8c7ccabd..3a69086a9d9d 100644
--- a/config/user.m4
+++ b/config/user.m4
@@ -31,7 +31,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
ZFS_AC_CONFIG_USER_MAKEDEV_IN_MKDEV
ZFS_AC_CONFIG_USER_ZFSEXEC
- AC_CHECK_FUNCS([execvpe issetugid mlockall strlcat strlcpy])
+ AC_CHECK_FUNCS([execvpe issetugid mlockall strlcat strlcpy gettid])
AC_SUBST(RM)
])
diff --git a/lib/libspl/assert.c b/lib/libspl/assert.c
index 9d44740d4e3c..185ec65cb894 100644
--- a/lib/libspl/assert.c
+++ b/lib/libspl/assert.c
@@ -22,9 +22,32 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2024, Rob Norris <robn@despairlabs.com>
+ */
#include <assert.h>
+#if defined(__linux__)
+#include <errno.h>
+#include <sys/prctl.h>
+#ifdef HAVE_GETTID
+#define libspl_gettid() gettid()
+#else
+#include <sys/syscall.h>
+#define libspl_gettid() ((pid_t)syscall(__NR_gettid))
+#endif
+#define libspl_getprogname() (program_invocation_short_name)
+#define libspl_getthreadname(buf, len) \
+ prctl(PR_GET_NAME, (unsigned long)(buf), 0, 0, 0)
+#elif defined(__FreeBSD__)
+#include <pthread_np.h>
+#define libspl_gettid() pthread_getthreadid_np()
+#define libspl_getprogname() getprogname()
+#define libspl_getthreadname(buf, len) \
+ pthread_getname_np(pthread_self(), buf, len);
+#endif
+
static boolean_t libspl_assert_ok = B_FALSE;
void
@@ -39,13 +62,22 @@ libspl_assertf(const char *file, const char *func, int line,
const char *format, ...)
{
va_list args;
+ char tname[64];
+
+ libspl_getthreadname(tname, sizeof (tname));
+
+ fprintf(stderr, "ASSERT at %s:%d:%s()\n", file, line, func);
va_start(args, format);
vfprintf(stderr, format, args);
- fprintf(stderr, "\n");
- fprintf(stderr, "ASSERT at %s:%d:%s()", file, line, func);
va_end(args);
+ fprintf(stderr, "\n"
+ " PID: %-8u COMM: %s\n"
+ " TID: %-8u NAME: %s\n",
+ getpid(), libspl_getprogname(),
+ libspl_gettid(), tname);
+
#if !__has_feature(attribute_analyzer_noreturn) && !defined(__COVERITY__)
if (libspl_assert_ok) {
return;