Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144422615
D50633.id156436.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
D50633.id156436.diff
View Options
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
@@ -31,15 +31,16 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "opt_ktrace.h"
-#include <sys/param.h>
-#include <sys/capsicum.h>
+#define EXTERR_CATEGORY EXTERR_KTRACE
#include <sys/systm.h>
+#include <sys/capsicum.h>
+#include <sys/exterrvar.h>
#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
+#include <sys/ktrace.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/malloc.h>
@@ -48,16 +49,15 @@
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
-#include <sys/unistd.h>
-#include <sys/vnode.h>
#include <sys/socket.h>
#include <sys/stat.h>
-#include <sys/ktrace.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/syslog.h>
#include <sys/sysproto.h>
+#include <sys/unistd.h>
+#include <sys/vnode.h>
#include <security/mac/mac_framework.h>
@@ -104,6 +104,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 +127,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 +1035,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,8 @@
#define EXTERR_CAT_MMAP 1
#define EXTERR_CAT_FILEDESC 2
+#define EXTERR_KTRACE 3 /* To allow inclusion of this
+ file into kern_ktrace.c */
#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
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 9, 9:02 AM (18 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28560716
Default Alt Text
D50633.id156436.diff (16 KB)
Attached To
Mode
D50633: ktrace: generate events on extended errors
Attached
Detach File
Event Timeline
Log In to Comment