git: a56fe703c206 - main - Provide user interface to retrieve reported extended errors

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sat, 31 May 2025 19:52:56 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=a56fe703c2065069cf756bbafcb3dc35c25f5343

commit a56fe703c2065069cf756bbafcb3dc35c25f5343
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-05-23 05:03:12 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-05-31 19:52:42 +0000

    Provide user interface to retrieve reported extended errors
    
    Reviewed by:    brooks
    Sponsored by:   The FreeBSD Foundation
    MFC after:      2 weeks
    Differential revision:  https://reviews.freebsd.org/D50483
---
 include/Makefile                      |  3 ++-
 include/exterr.h                      | 21 +++++++++++++++++++++
 lib/libc/gen/Makefile.inc             |  1 +
 lib/libc/gen/Symbol.map               |  2 ++
 lib/libc/gen/libc_interposing_table.c |  1 +
 lib/libc/gen/uexterr_format.c         | 31 +++++++++++++++++++++++++++++++
 lib/libc/gen/uexterr_gettext.c        | 24 ++++++++++++++++++++++++
 lib/libc/include/libc_private.h       |  5 +++++
 lib/libthr/thread/thr_syscalls.c      | 14 ++++++++++++--
 9 files changed, 99 insertions(+), 3 deletions(-)

diff --git a/include/Makefile b/include/Makefile
index 16d641b42a90..09b16d1f029e 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -17,7 +17,8 @@ SUBDIR_PARALLEL=
 INCS=	a.out.h ar.h assert.h bitstring.h byteswap.h \
 	complex.h cpio.h _ctype.h ctype.h \
 	db.h \
-	dirent.h dlfcn.h elf.h elf-hints.h endian.h err.h fmtmsg.h fnmatch.h \
+	dirent.h dlfcn.h elf.h elf-hints.h endian.h err.h exterr.h \
+	fmtmsg.h fnmatch.h \
 	fstab.h fts.h ftw.h getopt.h glob.h grp.h \
 	ieeefp.h ifaddrs.h \
 	inttypes.h iso646.h kenv.h langinfo.h libgen.h limits.h link.h \
diff --git a/include/exterr.h b/include/exterr.h
new file mode 100644
index 000000000000..c0273d72ce03
--- /dev/null
+++ b/include/exterr.h
@@ -0,0 +1,21 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software were developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ */
+
+#ifndef _EXTERR_H_
+#define	_EXTERR_H_
+
+#include <sys/cdefs.h>
+#include <sys/exterr_cat.h>
+
+__BEGIN_DECLS
+int uexterr_gettext(char *buf, size_t bufsz);
+__END_DECLS
+
+#endif
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index 6416effeb568..302fd3a004d1 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -159,6 +159,7 @@ SRCS+= \
 	ttyname.c \
 	ttyslot.c \
 	ualarm.c \
+	uexterr_format.c \
 	uexterr_gettext.c \
 	ulimit.c \
 	uname.c \
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
index 1683b3e42425..2ddca1f20e00 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -462,6 +462,7 @@ FBSD_1.8 {
 	psiginfo;
 	rtld_get_var;
 	rtld_set_var;
+	uexterr_gettext;
 };
 
 FBSDprivate_1.0 {
@@ -592,4 +593,5 @@ FBSDprivate_1.0 {
 	__fillcontextx2;
 	__getcontextx_size;
 	__makecontext;
+	__uexterr_format;
 };
diff --git a/lib/libc/gen/libc_interposing_table.c b/lib/libc/gen/libc_interposing_table.c
index d15d32711910..8eae6c7f5d95 100644
--- a/lib/libc/gen/libc_interposing_table.c
+++ b/lib/libc/gen/libc_interposing_table.c
@@ -43,6 +43,7 @@ interpos_func_t __libc_interposing[INTERPOS_MAX] = {
 	SLOT(spinunlock, __libc_spinunlock_stub),
 	SLOT(map_stacks_exec, __libc_map_stacks_exec),
 	SLOT(distribute_static_tls, __libc_distribute_static_tls),
+	SLOT(uexterr_gettext, __libc_uexterr_gettext),
 };
 #undef SLOT
 
diff --git a/lib/libc/gen/uexterr_format.c b/lib/libc/gen/uexterr_format.c
new file mode 100644
index 000000000000..32b57ffb6e1a
--- /dev/null
+++ b/lib/libc/gen/uexterr_format.c
@@ -0,0 +1,31 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software were developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ */
+
+#include <sys/types.h>
+#include <sys/exterrvar.h>
+#include <exterr.h>
+#include <stdio.h>
+#include <string.h>
+
+int
+__uexterr_format(const struct uexterror *ue, char *buf, size_t bufsz)
+{
+	if (bufsz > UEXTERROR_MAXLEN)
+		bufsz = UEXTERROR_MAXLEN;
+	if (ue->error == 0) {
+		strlcpy(buf, "No error", bufsz);
+		return (0);
+	}
+	snprintf(buf, bufsz,
+	    "errno %d category %u (src line %u) p1 %#jx p2 %#jx %s",
+	    ue->error, ue->cat, ue->src_line,
+	    (uintmax_t)ue->p1, (uintmax_t)ue->p2, ue->msg);
+	return (0);
+}
diff --git a/lib/libc/gen/uexterr_gettext.c b/lib/libc/gen/uexterr_gettext.c
index 1ee295556a4e..b4bb93cfdb50 100644
--- a/lib/libc/gen/uexterr_gettext.c
+++ b/lib/libc/gen/uexterr_gettext.c
@@ -1,7 +1,18 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software were developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ */
+
 #include <sys/types.h>
 #include <sys/exterrvar.h>
 #include <exterr.h>
 #include <string.h>
+#include "libc_private.h"
 
 static struct uexterror uexterr = {
 	.ver = UEXTERROR_VER,
@@ -13,3 +24,16 @@ uexterr_ctr(void)
 {
 	exterrctl(EXTERRCTL_ENABLE, 0, &uexterr);
 }
+
+int
+__libc_uexterr_gettext(char *buf, size_t bufsz)
+{
+	return (__uexterr_format(&uexterr, buf, bufsz));
+}
+
+int
+uexterr_gettext(char *buf, size_t bufsz)
+{
+	return (((int (*)(char *, size_t))
+	    __libc_interposing[INTERPOS_uexterr_gettext])(buf, bufsz));
+}
diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h
index 41b44456b6ee..1bc22f3931a5 100644
--- a/lib/libc/include/libc_private.h
+++ b/lib/libc/include/libc_private.h
@@ -251,6 +251,7 @@ enum {
 	INTERPOS_clock_nanosleep,
 	INTERPOS_distribute_static_tls,
 	INTERPOS_pdfork,
+	INTERPOS_uexterr_gettext,
 	INTERPOS_MAX
 };
 
@@ -380,4 +381,8 @@ struct __nl_cat_d *__catopen_l(const char *name, int type,
 int __strerror_rl(int errnum, char *strerrbuf, size_t buflen,
 	    struct _xlocale *locale);
 
+struct uexterror;
+int __uexterr_format(const struct uexterror *ue, char *buf, size_t bufsz);
+int __libc_uexterr_gettext(char *buf, size_t bufsz);
+
 #endif /* _LIBC_PRIVATE_H_ */
diff --git a/lib/libthr/thread/thr_syscalls.c b/lib/libthr/thread/thr_syscalls.c
index 22f9c1f68ec2..188374a30070 100644
--- a/lib/libthr/thread/thr_syscalls.c
+++ b/lib/libthr/thread/thr_syscalls.c
@@ -66,9 +66,9 @@
  */
 
 #include "namespace.h"
-#include <sys/types.h>
-#include <sys/mman.h>
 #include <sys/param.h>
+#include <sys/exterrvar.h>
+#include <sys/mman.h>
 #include <sys/select.h>
 #include <sys/signalvar.h>
 #include <sys/socket.h>
@@ -620,6 +620,15 @@ __thr_writev(int fd, const struct iovec *iov, int iovcnt)
 	return (ret);
 }
 
+static int
+__thr_uexterr_gettext(char *buf, size_t bufsz)
+{
+	struct pthread *curthread;
+
+	curthread = _get_curthread();
+	return (__uexterr_format(&curthread->uexterr, buf, bufsz));
+}
+
 void
 __thr_interpose_libc(void)
 {
@@ -675,6 +684,7 @@ __thr_interpose_libc(void)
 	SLOT(fdatasync);
 	SLOT(clock_nanosleep);
 	SLOT(pdfork);
+	SLOT(uexterr_gettext);
 #undef SLOT
 	*(__libc_interposing_slot(
 	    INTERPOS__pthread_mutex_init_calloc_cb)) =