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
This commit is contained in:
Konstantin Belousov 2025-05-23 08:03:12 +03:00
parent 98af94cae7
commit a56fe703c2
9 changed files with 99 additions and 3 deletions

View file

@ -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 \

21
include/exterr.h Normal file
View file

@ -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

View file

@ -159,6 +159,7 @@ SRCS+= \
ttyname.c \
ttyslot.c \
ualarm.c \
uexterr_format.c \
uexterr_gettext.c \
ulimit.c \
uname.c \

View file

@ -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;
};

View file

@ -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

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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_ */

View file

@ -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)) =