Page MenuHomeFreeBSD

D50633.id156369.diff
No OneTemporary

D50633.id156369.diff

diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -34,9 +34,11 @@
#include <sys/cdefs.h>
#include "opt_ktrace.h"
+#define EXTERR_CATEGORY EXTERR_KTRACE
#include <sys/param.h>
#include <sys/capsicum.h>
#include <sys/systm.h>
+#include <sys/exterrvar.h>
#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
@@ -104,6 +106,7 @@
struct ktr_fault ktr_fault;
struct ktr_faultend ktr_faultend;
struct ktr_struct_array ktr_struct_array;
+ struct ktr_exterr ktr_exterr;
} ktr_data;
STAILQ_ENTRY(ktr_request) ktr_list;
};
@@ -126,6 +129,7 @@
[KTR_STRUCT_ARRAY] = sizeof(struct ktr_struct_array),
[KTR_ARGS] = 0,
[KTR_ENVS] = 0,
+ [KTR_EXTERR] = sizeof(struct ktr_exterr),
};
static STAILQ_HEAD(, ktr_request) ktr_free;
@@ -1033,8 +1037,35 @@
ktr_enqueuerequest(td, req);
ktrace_exit(td);
}
+
+void
+ktrexterr(struct thread *td)
+{
+ struct ktr_request *req;
+ struct ktr_exterr *ktre;
+
+ if (!KTRPOINT(td, KTR_EXTERR))
+ return;
+
+ req = ktr_getrequest(KTR_EXTERR);
+ if (req == NULL)
+ return;
+ ktre = &req->ktr_data.ktr_exterr;
+ if (exterr_to_ue(td, &ktre->ue) == 0)
+ ktr_enqueuerequest(td, req);
+ else
+ ktr_freerequest(req);
+ ktrace_exit(td);
+}
#endif /* KTRACE */
+#ifndef KTRACE
+void
+ktrexterr(struct thread *td __unused)
+{
+}
+#endif
+
/* Interface and common routines */
#ifndef _SYS_SYSPROTO_H_
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -2202,6 +2202,23 @@
return (kcmp_cmp((uintptr_t)fp1->f_data, (uintptr_t)fp2->f_data));
}
+int
+exterr_to_ue(struct thread *td, struct uexterror *ue)
+{
+ if ((td->td_pflags2 & TDP2_EXTERR) == 0)
+ return (ENOENT);
+
+ memset(ue, 0, sizeof(*ue));
+ ue->error = td->td_kexterr.error;
+ ue->cat = td->td_kexterr.cat;
+ ue->src_line = td->td_kexterr.src_line;
+ ue->p1 = td->td_kexterr.p1;
+ ue->p2 = td->td_kexterr.p2;
+ if (td->td_kexterr.msg != NULL)
+ strlcpy(ue->msg, td->td_kexterr.msg, sizeof(ue->msg));
+ return (0);
+}
+
void
exterr_copyout(struct thread *td)
{
@@ -2215,18 +2232,11 @@
uloc = (char *)td->td_exterr_ptr + __offsetof(struct uexterror,
error);
- if ((td->td_pflags2 & TDP2_EXTERR) == 0) {
+ error = exterr_to_ue(td, &ue);
+ if (error != 0) {
ue.error = 0;
sz = sizeof(ue.error);
} else {
- memset(&ue, 0, sizeof(ue));
- ue.error = td->td_kexterr.error;
- ue.cat = td->td_kexterr.cat;
- ue.src_line = td->td_kexterr.src_line;
- ue.p1 = td->td_kexterr.p1;
- ue.p2 = td->td_kexterr.p2;
- if (td->td_kexterr.msg != NULL)
- strlcpy(ue.msg, td->td_kexterr.msg, sizeof(ue.msg));
sz = sizeof(ue) - __offsetof(struct uexterror, error);
}
error = copyout(&ue.error, uloc, sz);
diff --git a/sys/sys/_uexterror.h b/sys/sys/_uexterror.h
new file mode 100644
--- /dev/null
+++ b/sys/sys/_uexterror.h
@@ -0,0 +1,27 @@
+/*-
+ * 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 _SYS__UEXTERROR_H_
+#define _SYS__UEXTERROR_H_
+
+#include <sys/_types.h>
+
+struct uexterror {
+ __uint32_t ver;
+ __uint32_t error;
+ __uint32_t cat;
+ __uint32_t src_line;
+ __uint64_t p1;
+ __uint64_t p2;
+ __uint64_t rsrv1[4];
+ char msg[128];
+};
+
+#endif
diff --git a/sys/sys/exterr_cat.h b/sys/sys/exterr_cat.h
--- a/sys/sys/exterr_cat.h
+++ b/sys/sys/exterr_cat.h
@@ -13,6 +13,7 @@
#define EXTERR_CAT_MMAP 1
#define EXTERR_CAT_FILEDESC 2
+#define EXTERR_KTRACE 3 /* To allow inclusion */
#endif
diff --git a/sys/sys/exterrvar.h b/sys/sys/exterrvar.h
--- a/sys/sys/exterrvar.h
+++ b/sys/sys/exterrvar.h
@@ -12,19 +12,8 @@
#define _SYS_EXTERRVAR_H_
#include <sys/_exterr.h>
+#include <sys/_uexterror.h>
#include <sys/exterr_cat.h>
-#include <sys/types.h>
-
-struct uexterror {
- uint32_t ver;
- uint32_t error;
- uint32_t cat;
- uint32_t src_line;
- uint64_t p1;
- uint64_t p2;
- uint64_t rsrv1[4];
- char msg[128];
-};
#define UEXTERROR_MAXLEN 256
@@ -57,13 +46,19 @@
_Td->td_kexterr.p1 = (uintptr_t)pp1; \
_Td->td_kexterr.p2 = (uintptr_t)pp2; \
_Td->td_kexterr.src_line = __LINE__; \
+ ktrexterr(_Td); \
} \
} while (0)
#define SET_ERROR0(eerror, mmsg) SET_ERROR2(eerror, mmsg, 0, 0)
#define SET_ERROR1(eerror, mmsg, pp1) SET_ERROR2(eerror, mmsg, pp1, 0)
+int exterr_to_ue(struct thread *td, struct uexterror *ue);
+void ktrexterr(struct thread *td);
+
#else /* _KERNEL */
+#include <sys/types.h>
+
__BEGIN_DECLS
int exterrctl(u_int op, u_int flags, void *ptr);
__END_DECLS
diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h
--- a/sys/sys/ktrace.h
+++ b/sys/sys/ktrace.h
@@ -36,6 +36,7 @@
#include <sys/caprights.h>
#include <sys/signal.h>
#include <sys/socket.h>
+#include <sys/_uexterror.h>
#include <sys/_uio.h>
/*
@@ -272,6 +273,14 @@
*/
#define KTR_ENVS 17
+/*
+ * KTR_EXTERR - extended error reported
+ */
+#define KTR_EXTERR 18
+struct ktr_exterr {
+ struct uexterror ue;
+};
+
/*
* KTR_DROP - If this bit is set in ktr_type, then at least one event
* between the previous record and this record was dropped.
@@ -306,6 +315,7 @@
#define KTRFAC_STRUCT_ARRAY (1<<KTR_STRUCT_ARRAY)
#define KTRFAC_ARGS (1<<KTR_ARGS)
#define KTRFAC_ENVS (1<<KTR_ENVS)
+#define KTRFAC_EXTERR (1<<KTR_EXTERR)
/*
* trace flags (also in p_traceflags)
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -87,39 +87,40 @@
#include <casper/cap_pwd.h>
#endif
-int fetchprocinfo(struct ktr_header *, u_int *);
-u_int findabi(struct ktr_header *);
-int fread_tail(void *, int, int);
-void dumpheader(struct ktr_header *, u_int);
-void dumptimeval(struct ktr_header_v0 *kth);
-void dumptimespec(struct ktr_header *kth);
-void ktrsyscall(struct ktr_syscall *, u_int);
-void ktrsysret(struct ktr_sysret *, u_int);
-void ktrnamei(char *, int);
-void hexdump(char *, int, int);
-void visdump(char *, int, int);
-void ktrgenio(struct ktr_genio *, int);
-void ktrpsig(struct ktr_psig *);
-void ktrcsw(struct ktr_csw *);
-void ktrcsw_old(struct ktr_csw_old *);
-void ktruser(int, void *);
-void ktrcaprights(cap_rights_t *);
-void ktritimerval(struct itimerval *it);
-void ktrsockaddr(struct sockaddr *);
-void ktrsplice(struct splice *);
-void ktrstat(struct stat *);
-void ktrstruct(char *, size_t);
-void ktrcapfail(struct ktr_cap_fail *);
-void ktrfault(struct ktr_fault *);
-void ktrfaultend(struct ktr_faultend *);
-void ktrkevent(struct kevent *);
-void ktrpollfd(struct pollfd *);
-void ktrstructarray(struct ktr_struct_array *, size_t);
-void ktrbitset(char *, struct bitset *, size_t);
-void ktrsyscall_freebsd(struct ktr_syscall *ktr, register_t **resip,
+static int fetchprocinfo(struct ktr_header *, u_int *);
+static u_int findabi(struct ktr_header *);
+static int fread_tail(void *, int, int);
+static void dumpheader(struct ktr_header *, u_int);
+static void dumptimeval(struct ktr_header_v0 *kth);
+static void dumptimespec(struct ktr_header *kth);
+static void ktrsyscall(struct ktr_syscall *, u_int);
+static void ktrsysret(struct ktr_sysret *, u_int);
+static void ktrnamei(char *, int);
+static void hexdump(char *, int, int);
+static void visdump(char *, int, int);
+static void ktrgenio(struct ktr_genio *, int);
+static void ktrpsig(struct ktr_psig *);
+static void ktrcsw(struct ktr_csw *);
+static void ktrcsw_old(struct ktr_csw_old *);
+static void ktruser(int, void *);
+static void ktrcaprights(cap_rights_t *);
+static void ktritimerval(struct itimerval *it);
+static void ktrsockaddr(struct sockaddr *);
+static void ktrsplice(struct splice *);
+static void ktrstat(struct stat *);
+static void ktrstruct(char *, size_t);
+static void ktrcapfail(struct ktr_cap_fail *);
+static void ktrfault(struct ktr_fault *);
+static void ktrfaultend(struct ktr_faultend *);
+static void ktrkevent(struct kevent *);
+static void ktrpollfd(struct pollfd *);
+static void ktrstructarray(struct ktr_struct_array *, size_t);
+static void ktrbitset(char *, struct bitset *, size_t);
+static void ktrsyscall_freebsd(struct ktr_syscall *ktr, register_t **resip,
int *resnarg, char *resc, u_int sv_flags);
-void ktrexecve(char *, int);
-void usage(void);
+static void ktrexecve(char *, int);
+static void ktrexterr(struct ktr_exterr *);
+static void usage(void);
#define TIMESTAMP_NONE 0x0
#define TIMESTAMP_ABSOLUTE 0x1
@@ -521,6 +522,8 @@
case KTR_ENVS:
ktrexecve(m, ktrlen);
break;
+ case KTR_EXTERR:
+ ktrexterr((struct ktr_exterr *)m);
default:
printf("\n");
break;
@@ -531,7 +534,7 @@
return 0;
}
-int
+static int
fread_tail(void *buf, int size, int num)
{
int i;
@@ -543,7 +546,7 @@
return (i);
}
-int
+static int
fetchprocinfo(struct ktr_header *kth, u_int *flags)
{
struct proc_info *pi;
@@ -578,7 +581,7 @@
return (0);
}
-u_int
+static u_int
findabi(struct ktr_header *kth)
{
struct proc_info *pi;
@@ -591,7 +594,7 @@
return (0);
}
-void
+static void
dumptimeval(struct ktr_header_v0 *kth)
{
static struct timeval prevtime, prevtime_e;
@@ -625,7 +628,7 @@
}
}
-void
+static void
dumptimespec(struct ktr_header *kth)
{
static struct timespec prevtime, prevtime_e;
@@ -659,7 +662,26 @@
}
}
-void
+static const char * const hdr_names[] = {
+ [KTR_SYSCALL] = "CALL",
+ [KTR_SYSRET] = "RET ",
+ [KTR_NAMEI] = "NAMI",
+ [KTR_GENIO] = "GIO ",
+ [KTR_PSIG] = "PSIG",
+ [KTR_CSW] = "CSW ",
+ [KTR_USER] = "USER",
+ [KTR_STRUCT] = "STRU",
+ [KTR_STRUCT_ARRAY] = "STRU",
+ [KTR_SYSCTL] = "SCTL",
+ [KTR_CAPFAIL] = "CAP ",
+ [KTR_FAULT] = "PFLT",
+ [KTR_FAULTEND] = "PRET",
+ [KTR_ARGS] = "ARGS",
+ [KTR_ENVS] = "ENVS",
+ [KTR_EXTERR] = "EERR",
+};
+
+static void
dumpheader(struct ktr_header *kth, u_int sv_flags)
{
static char unknown[64];
@@ -667,53 +689,12 @@
const char *arch;
const char *type;
- switch (kth->ktr_type) {
- case KTR_SYSCALL:
- type = "CALL";
- break;
- case KTR_SYSRET:
- type = "RET ";
- break;
- case KTR_NAMEI:
- type = "NAMI";
- break;
- case KTR_GENIO:
- type = "GIO ";
- break;
- case KTR_PSIG:
- type = "PSIG";
- break;
- case KTR_CSW:
- type = "CSW ";
- break;
- case KTR_USER:
- type = "USER";
- break;
- case KTR_STRUCT:
- case KTR_STRUCT_ARRAY:
- type = "STRU";
- break;
- case KTR_SYSCTL:
- type = "SCTL";
- break;
- case KTR_CAPFAIL:
- type = "CAP ";
- break;
- case KTR_FAULT:
- type = "PFLT";
- break;
- case KTR_FAULTEND:
- type = "PRET";
- break;
- case KTR_ARGS:
- type = "ARGS";
- break;
- case KTR_ENVS:
- type = "ENVS";
- break;
- default:
- sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
+ if (kth->ktr_type < 0 || (size_t)kth->ktr_type >= nitems(hdr_names)) {
+ snprintf(unknown, sizeof(unknown), "UNKNOWN(%d)",
+ kth->ktr_type);
type = unknown;
+ } else {
+ type = hdr_names[kth->ktr_type];
}
/*
@@ -826,7 +807,7 @@
printf("SIG %d", signo);
}
-void
+static void
ktrsyscall(struct ktr_syscall *ktr, u_int sv_flags)
{
int narg = ktr->ktr_narg;
@@ -862,7 +843,7 @@
putchar('\n');
}
-void
+static void
ktrsyscall_freebsd(struct ktr_syscall *ktr, register_t **resip,
int *resnarg, char *resc, u_int sv_flags)
{
@@ -1619,7 +1600,7 @@
*resnarg = narg;
}
-void
+static void
ktrsysret(struct ktr_sysret *ktr, u_int sv_flags)
{
register_t ret = ktr->ktr_retval;
@@ -1652,13 +1633,13 @@
putchar('\n');
}
-void
+static void
ktrnamei(char *cp, int len)
{
printf("\"%.*s\"\n", len, cp);
}
-void
+static void
ktrexecve(char *m, int len)
{
int i = 0;
@@ -1673,7 +1654,7 @@
printf("\n");
}
-void
+static void
hexdump(char *p, int len, int screenwidth)
{
int n, i;
@@ -1719,7 +1700,7 @@
printf("\n");
}
-void
+static void
visdump(char *dp, int datalen, int screenwidth)
{
int col = 0;
@@ -1765,7 +1746,7 @@
printf("\"\n");
}
-void
+static void
ktrgenio(struct ktr_genio *ktr, int len)
{
int datalen = len - sizeof (struct ktr_genio);
@@ -1803,7 +1784,7 @@
visdump(dp, datalen, screenwidth);
}
-void
+static void
ktrpsig(struct ktr_psig *psig)
{
const char *str;
@@ -1824,21 +1805,21 @@
putchar('\n');
}
-void
+static void
ktrcsw_old(struct ktr_csw_old *cs)
{
printf("%s %s\n", cs->out ? "stop" : "resume",
cs->user ? "user" : "kernel");
}
-void
+static void
ktrcsw(struct ktr_csw *cs)
{
printf("%s %s \"%s\"\n", cs->out ? "stop" : "resume",
cs->user ? "user" : "kernel", cs->wmesg);
}
-void
+static void
ktruser(int len, void *p)
{
unsigned char *cp;
@@ -1858,7 +1839,7 @@
printf("\n");
}
-void
+static void
ktrcaprights(cap_rights_t *rightsp)
{
@@ -1874,7 +1855,7 @@
printf("{%ld, %ld}", (long)tv->tv_sec, tv->tv_usec);
}
-void
+static void
ktritimerval(struct itimerval *it)
{
@@ -1885,7 +1866,7 @@
printf(" }\n");
}
-void
+static void
ktrsockaddr(struct sockaddr *sa)
{
/*
@@ -1960,7 +1941,7 @@
printf(" }\n");
}
-void
+static void
ktrsplice(struct splice *sp)
{
printf("struct splice { fd=%d, max=%#jx, idle=%jd.%06jd }\n",
@@ -1968,7 +1949,7 @@
(intmax_t)sp->sp_idle.tv_usec);
}
-void
+static void
ktrstat(struct stat *statp)
{
char mode[12], timestr[PATH_MAX + 4];
@@ -2073,7 +2054,7 @@
printf(" }\n");
}
-void
+static void
ktrbitset(char *name, struct bitset *set, size_t setlen)
{
int i, maxi, c = 0;
@@ -2097,7 +2078,7 @@
printf(" ]\n");
}
-void
+static void
ktrstruct(char *buf, size_t buflen)
{
char *name, *data;
@@ -2174,7 +2155,7 @@
printf("invalid record\n");
}
-void
+static void
ktrcapfail(struct ktr_cap_fail *ktr)
{
union ktr_cap_data *kcd = &ktr->cap_data;
@@ -2249,7 +2230,7 @@
printf("\n");
}
-void
+static void
ktrfault(struct ktr_fault *ktr)
{
@@ -2258,7 +2239,7 @@
printf("\n");
}
-void
+static void
ktrfaultend(struct ktr_faultend *ktr)
{
const char *str;
@@ -2271,7 +2252,7 @@
printf("\n");
}
-void
+static void
ktrkevent(struct kevent *kev)
{
@@ -2302,7 +2283,7 @@
printf(", data=%#jx, udata=%p }", (uintmax_t)kev->data, kev->udata);
}
-void
+static void
ktrpollfd(struct pollfd *pfd)
{
@@ -2314,7 +2295,7 @@
printf("}");
}
-void
+static void
ktrstructarray(struct ktr_struct_array *ksa, size_t buflen)
{
struct kevent kev;
@@ -2420,7 +2401,18 @@
return;
}
-void
+static void
+ktrexterr(struct ktr_exterr *ke)
+{
+ struct uexterror *ue;
+
+ ue = &ke->ue;
+ printf("{ 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);
+}
+
+static void
usage(void)
{
fprintf(stderr, "usage: kdump [-dEnlHRrSsTA] [-f trfile] "
diff --git a/usr.bin/ktrace/ktrace.h b/usr.bin/ktrace/ktrace.h
--- a/usr.bin/ktrace/ktrace.h
+++ b/usr.bin/ktrace/ktrace.h
@@ -32,7 +32,7 @@
#define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \
KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_USER | \
KTRFAC_STRUCT | KTRFAC_SYSCTL | KTRFAC_STRUCT_ARRAY | \
- KTRFAC_ARGS | KTRFAC_ENVS)
+ KTRFAC_ARGS | KTRFAC_ENVS | KTRFAC_EXTERR)
#define PROC_ABI_POINTS (KTRFAC_PROCCTOR | KTRFAC_PROCDTOR)
diff --git a/usr.bin/ktrace/ktrace.1 b/usr.bin/ktrace/ktrace.1
--- a/usr.bin/ktrace/ktrace.1
+++ b/usr.bin/ktrace/ktrace.1
@@ -150,9 +150,13 @@
trace
.Xr execve 2
environment variables
+.It Cm x
+trace
+.Xr exterr 2
+extended errors reports from kernel
.It Cm +
trace the default set of trace points -
-.Cm a, c , e, i , n , s , t , u , y
+.Cm a, c , e, i , n , s , t , u , x, y
.El
.It Ar command
Execute
diff --git a/usr.bin/ktrace/subr.c b/usr.bin/ktrace/subr.c
--- a/usr.bin/ktrace/subr.c
+++ b/usr.bin/ktrace/subr.c
@@ -87,6 +87,8 @@
case 'e':
facs |= KTRFAC_ENVS;
break;
+ case 'x':
+ facs |= KTRFAC_EXTERR;
case '+':
facs |= DEF_POINTS;
break;

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 9:18 AM (18 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28562299
Default Alt Text
D50633.id156369.diff (15 KB)

Event Timeline