2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 4. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 static const char copyright
[] =
32 "@(#) Copyright (c) 1988, 1993\n\
33 The Regents of the University of California. All rights reserved.\n";
38 static char sccsid
[] = "@(#)kdump.c 8.1 (Berkeley) 6/6/93";
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
46 #include <sys/errno.h>
48 #include <sys/param.h>
49 #include <sys/capsicum.h>
50 #include <sys/errno.h>
55 #include <sys/ktrace.h>
56 #include <sys/ioctl.h>
57 #include <sys/socket.h>
59 #include <sys/sysent.h>
62 #include <sys/queue.h>
67 #include <arpa/inet.h>
68 #include <netinet/in.h>
80 #include <sysdecode.h>
86 #include "kdump_subr.h"
89 #include <libcasper.h>
91 #include <casper/cap_grp.h>
92 #include <casper/cap_pwd.h>
95 u_int
abidump(struct ktr_header
*);
96 int fetchprocinfo(struct ktr_header
*, u_int
*);
97 int fread_tail(void *, int, int);
98 void dumpheader(struct ktr_header
*);
99 void ktrsyscall(struct ktr_syscall
*, u_int
);
100 void ktrsysret(struct ktr_sysret
*, u_int
);
101 void ktrnamei(char *, int);
102 void hexdump(char *, int, int);
103 void visdump(char *, int, int);
104 void ktrgenio(struct ktr_genio
*, int);
105 void ktrpsig(struct ktr_psig
*);
106 void ktrcsw(struct ktr_csw
*);
107 void ktrcsw_old(struct ktr_csw_old
*);
108 void ktruser_malloc(void *);
109 void ktruser_rtld(int, void *);
110 void ktruser(int, void *);
111 void ktrcaprights(cap_rights_t
*);
112 void ktritimerval(struct itimerval
*it
);
113 void ktrsockaddr(struct sockaddr
*);
114 void ktrstat(struct stat
*);
115 void ktrstruct(char *, size_t);
116 void ktrcapfail(struct ktr_cap_fail
*);
117 void ktrfault(struct ktr_fault
*);
118 void ktrfaultend(struct ktr_faultend
*);
119 void limitfd(int fd
);
122 #define TIMESTAMP_NONE 0x0
123 #define TIMESTAMP_ABSOLUTE 0x1
124 #define TIMESTAMP_ELAPSED 0x2
125 #define TIMESTAMP_RELATIVE 0x4
127 extern const char *signames
[];
129 static int timestamp
, decimal
, fancy
= 1, suppressdata
, tail
, threads
, maxdata
,
130 resolv
= 0, abiflag
= 0, syscallno
= 0;
131 static const char *tracefile
= DEF_TRACEFILE
;
132 static struct ktr_header ktr_header
;
134 #define TIME_FORMAT "%b %e %T %Y"
135 #define eqs(s1, s2) (strcmp((s1), (s2)) == 0)
137 #define print_number(i,n,c) do { \
139 printf("%c%jd", c, (intmax_t)*i); \
141 printf("%c%#jx", c, (uintmax_t)(u_register_t)*i); \
149 TAILQ_ENTRY(proc_info
) info
;
154 static TAILQ_HEAD(trace_procs
, proc_info
) trace_procs
;
156 #ifdef HAVE_LIBCASPER
157 static cap_channel_t
*cappwd
, *capgrp
;
165 * Cache NLS data before entering capability mode.
166 * XXXPJD: There should be strerror_init() and strsignal_init() in libc.
168 (void)catopen("libc", NL_CAT_LOCALE
);
177 * Allow localtime(3) to cache /etc/localtime content before entering
179 * XXXPJD: There should be localtime_init() in libc.
182 (void)localtime(<ime
);
185 #ifdef HAVE_LIBCASPER
187 cappwdgrp_setup(cap_channel_t
**cappwdp
, cap_channel_t
**capgrpp
)
189 cap_channel_t
*capcas
, *cappwdloc
, *capgrploc
;
190 const char *cmds
[1], *fields
[1];
193 if (capcas
== NULL
) {
194 err(1, "unable to create casper process");
197 cappwdloc
= cap_service_open(capcas
, "system.pwd");
198 capgrploc
= cap_service_open(capcas
, "system.grp");
199 /* Casper capability no longer needed. */
201 if (cappwdloc
== NULL
|| capgrploc
== NULL
) {
202 if (cappwdloc
== NULL
)
203 warn("unable to open system.pwd service");
204 if (capgrploc
== NULL
)
205 warn("unable to open system.grp service");
208 /* Limit system.pwd to only getpwuid() function and pw_name field. */
209 cmds
[0] = "getpwuid";
210 if (cap_pwd_limit_cmds(cappwdloc
, cmds
, 1) < 0)
211 err(1, "unable to limit system.pwd service");
212 fields
[0] = "pw_name";
213 if (cap_pwd_limit_fields(cappwdloc
, fields
, 1) < 0)
214 err(1, "unable to limit system.pwd service");
215 /* Limit system.grp to only getgrgid() function and gr_name field. */
216 cmds
[0] = "getgrgid";
217 if (cap_grp_limit_cmds(capgrploc
, cmds
, 1) < 0)
218 err(1, "unable to limit system.grp service");
219 fields
[0] = "gr_name";
220 if (cap_grp_limit_fields(capgrploc
, fields
, 1) < 0)
221 err(1, "unable to limit system.grp service");
223 *cappwdp
= cappwdloc
;
224 *capgrpp
= capgrploc
;
227 #endif /* HAVE_LIBCASPER */
230 main(int argc
, char *argv
[])
232 int ch
, ktrlen
, size
;
234 int trpoints
= ALL_POINTS
;
239 setlocale(LC_CTYPE
, "");
241 timestamp
= TIMESTAMP_NONE
;
243 while ((ch
= getopt(argc
,argv
,"f:dElm:np:AHRrSsTt:")) != -1)
258 maxdata
= atoi(optarg
);
276 timestamp
|= TIMESTAMP_ELAPSED
;
282 timestamp
|= TIMESTAMP_RELATIVE
;
285 timestamp
|= TIMESTAMP_ABSOLUTE
;
288 trpoints
= getpoints(optarg
);
290 errx(1, "unknown trace point in %s", optarg
);
299 m
= malloc(size
= 1025);
301 errx(1, "%s", strerror(ENOMEM
));
302 if (strcmp(tracefile
, "-") != 0)
303 if (!freopen(tracefile
, "r", stdin
))
304 err(1, "%s", tracefile
);
308 #ifdef HAVE_LIBCASPER
310 if (cappwdgrp_setup(&cappwd
, &capgrp
) < 0) {
315 if (resolv
== 0 || (cappwd
!= NULL
&& capgrp
!= NULL
)) {
316 if (cap_enter() < 0 && errno
!= ENOSYS
)
317 err(1, "unable to enter capability mode");
321 if (cap_enter() < 0 && errno
!= ENOSYS
)
322 err(1, "unable to enter capability mode");
325 limitfd(STDIN_FILENO
);
326 limitfd(STDOUT_FILENO
);
327 limitfd(STDERR_FILENO
);
329 TAILQ_INIT(&trace_procs
);
331 while (fread_tail(&ktr_header
, sizeof(struct ktr_header
), 1)) {
332 if (ktr_header
.ktr_type
& KTR_DROP
) {
333 ktr_header
.ktr_type
&= ~KTR_DROP
;
334 if (!drop_logged
&& threads
) {
336 "%6jd %6jd %-8.*s Events dropped.\n",
337 (intmax_t)ktr_header
.ktr_pid
,
338 ktr_header
.ktr_tid
> 0 ?
339 (intmax_t)ktr_header
.ktr_tid
: 0,
340 MAXCOMLEN
, ktr_header
.ktr_comm
);
342 } else if (!drop_logged
) {
343 printf("%6jd %-8.*s Events dropped.\n",
344 (intmax_t)ktr_header
.ktr_pid
, MAXCOMLEN
,
345 ktr_header
.ktr_comm
);
349 if (trpoints
& (1<<ktr_header
.ktr_type
))
350 if (pid
== 0 || ktr_header
.ktr_pid
== pid
||
351 ktr_header
.ktr_tid
== pid
)
352 dumpheader(&ktr_header
);
353 if ((ktrlen
= ktr_header
.ktr_len
) < 0)
354 errx(1, "bogus length 0x%x", ktrlen
);
356 m
= realloc(m
, ktrlen
+1);
358 errx(1, "%s", strerror(ENOMEM
));
361 if (ktrlen
&& fread_tail(m
, ktrlen
, 1) == 0)
362 errx(1, "data too short");
363 if (fetchprocinfo(&ktr_header
, (u_int
*)m
) != 0)
365 sv_flags
= abidump(&ktr_header
);
366 if (pid
&& ktr_header
.ktr_pid
!= pid
&&
367 ktr_header
.ktr_tid
!= pid
)
369 if ((trpoints
& (1<<ktr_header
.ktr_type
)) == 0)
372 switch (ktr_header
.ktr_type
) {
374 ktrsyscall((struct ktr_syscall
*)m
, sv_flags
);
377 ktrsysret((struct ktr_sysret
*)m
, sv_flags
);
384 ktrgenio((struct ktr_genio
*)m
, ktrlen
);
387 ktrpsig((struct ktr_psig
*)m
);
390 if (ktrlen
== sizeof(struct ktr_csw_old
))
391 ktrcsw_old((struct ktr_csw_old
*)m
);
393 ktrcsw((struct ktr_csw
*)m
);
399 ktrstruct(m
, ktrlen
);
402 ktrcapfail((struct ktr_cap_fail
*)m
);
405 ktrfault((struct ktr_fault
*)m
);
408 ktrfaultend((struct ktr_faultend
*)m
);
426 cap_rights_init(&rights
, CAP_FSTAT
);
431 cap_rights_set(&rights
, CAP_READ
);
434 cap_rights_set(&rights
, CAP_IOCTL
, CAP_WRITE
);
435 cmd
= TIOCGETA
; /* required by isatty(3) in printf(3) */
438 cap_rights_set(&rights
, CAP_WRITE
);
440 cap_rights_set(&rights
, CAP_IOCTL
);
448 if (cap_rights_limit(fd
, &rights
) < 0 && errno
!= ENOSYS
)
449 err(1, "unable to limit rights for descriptor %d", fd
);
450 if (cmd
!= 0 && cap_ioctls_limit(fd
, &cmd
, 1) < 0 && errno
!= ENOSYS
)
451 err(1, "unable to limit ioctls for descriptor %d", fd
);
455 fread_tail(void *buf
, int size
, int num
)
459 while ((i
= fread(buf
, size
, num
, stdin
)) == 0 && tail
) {
467 fetchprocinfo(struct ktr_header
*kth
, u_int
*flags
)
469 struct proc_info
*pi
;
471 switch (kth
->ktr_type
) {
473 TAILQ_FOREACH(pi
, &trace_procs
, info
) {
474 if (pi
->pid
== kth
->ktr_pid
) {
475 TAILQ_REMOVE(&trace_procs
, pi
, info
);
479 pi
= malloc(sizeof(struct proc_info
));
481 errx(1, "%s", strerror(ENOMEM
));
482 pi
->sv_flags
= *flags
;
483 pi
->pid
= kth
->ktr_pid
;
484 TAILQ_INSERT_TAIL(&trace_procs
, pi
, info
);
488 TAILQ_FOREACH(pi
, &trace_procs
, info
) {
489 if (pi
->pid
== kth
->ktr_pid
) {
490 TAILQ_REMOVE(&trace_procs
, pi
, info
);
502 abidump(struct ktr_header
*kth
)
504 struct proc_info
*pi
;
509 TAILQ_FOREACH(pi
, &trace_procs
, info
) {
510 if (pi
->pid
== kth
->ktr_pid
) {
511 flags
= pi
->sv_flags
;
519 switch (flags
& SV_ABI_MASK
) {
526 case SV_ABI_CLOUDABI
:
536 else if (flags
& SV_ILP32
)
541 printf("%s%s ", abi
, arch
);
547 dumpheader(struct ktr_header
*kth
)
549 static char unknown
[64];
550 static struct timeval prevtime
, prevtime_e
, temp
;
554 switch (kth
->ktr_type
) {
596 sprintf(unknown
, "UNKNOWN(%d)", kth
->ktr_type
);
601 * The ktr_tid field was previously the ktr_buffer field, which held
602 * the kernel pointer value for the buffer associated with data
603 * following the record header. It now holds a threadid, but only
604 * for trace files after the change. Older trace files still contain
605 * kernel pointers. Detect this and suppress the results by printing
606 * negative tid's as 0.
609 printf("%6jd %6jd %-8.*s ", (intmax_t)kth
->ktr_pid
,
610 kth
->ktr_tid
> 0 ? (intmax_t)kth
->ktr_tid
: 0,
611 MAXCOMLEN
, kth
->ktr_comm
);
613 printf("%6jd %-8.*s ", (intmax_t)kth
->ktr_pid
, MAXCOMLEN
,
616 if (timestamp
& TIMESTAMP_ABSOLUTE
) {
617 printf("%jd.%06ld ", (intmax_t)kth
->ktr_time
.tv_sec
,
618 kth
->ktr_time
.tv_usec
);
620 if (timestamp
& TIMESTAMP_ELAPSED
) {
621 if (prevtime_e
.tv_sec
== 0)
622 prevtime_e
= kth
->ktr_time
;
623 timevalsub(&kth
->ktr_time
, &prevtime_e
);
624 printf("%jd.%06ld ", (intmax_t)kth
->ktr_time
.tv_sec
,
625 kth
->ktr_time
.tv_usec
);
626 timevaladd(&kth
->ktr_time
, &prevtime_e
);
628 if (timestamp
& TIMESTAMP_RELATIVE
) {
629 if (prevtime
.tv_sec
== 0)
630 prevtime
= kth
->ktr_time
;
631 temp
= kth
->ktr_time
;
632 timevalsub(&kth
->ktr_time
, &prevtime
);
633 if ((intmax_t)kth
->ktr_time
.tv_sec
< 0) {
634 kth
->ktr_time
= prevtime
;
636 timevalsub(&kth
->ktr_time
, &prevtime
);
642 printf("%s%jd.%06ld ", sign
, (intmax_t)kth
->ktr_time
.tv_sec
,
643 kth
->ktr_time
.tv_usec
);
649 #include <sys/syscall.h>
652 ioctlname(unsigned long val
)
656 str
= sysdecode_ioctlname(val
);
665 static enum sysdecode_abi
666 syscallabi(u_int sv_flags
)
670 return (SYSDECODE_ABI_FREEBSD
);
671 switch (sv_flags
& SV_ABI_MASK
) {
673 return (SYSDECODE_ABI_FREEBSD
);
674 #if defined(__amd64__) || defined(__i386__)
677 if (sv_flags
& SV_ILP32
)
678 return (SYSDECODE_ABI_LINUX32
);
680 return (SYSDECODE_ABI_LINUX
);
682 #if defined(__aarch64__) || defined(__amd64__)
683 case SV_ABI_CLOUDABI
:
684 return (SYSDECODE_ABI_CLOUDABI64
);
687 return (SYSDECODE_ABI_UNKNOWN
);
692 syscallname(u_int code
, u_int sv_flags
)
696 name
= sysdecode_syscallname(syscallabi(sv_flags
), code
);
698 printf("[%d]", code
);
702 printf("[%d]", code
);
707 ktrsyscall(struct ktr_syscall
*ktr
, u_int sv_flags
)
709 int narg
= ktr
->ktr_narg
;
713 syscallname(ktr
->ktr_code
, sv_flags
);
714 ip
= &ktr
->ktr_args
[0];
719 (sv_flags
& SV_ABI_MASK
) == SV_ABI_FREEBSD
)) {
720 switch (ktr
->ktr_code
) {
738 atfdname(*ip
, decimal
);
744 switch (ktr
->ktr_code
) {
746 print_number(ip
, narg
, c
);
764 print_number(ip
, narg
, c
);
772 print_number(ip
, narg
, c
);
774 flagsandmodename(ip
[0], ip
[1], decimal
);
779 print_number(ip
, narg
, c
);
780 print_number(ip
, narg
, c
);
782 * A flags value of zero is valid for
783 * wait4() but not for wait6(), so
784 * handle zero special here.
787 print_number(ip
, narg
, c
);
797 idtypename(*ip
, decimal
);
801 print_number(ip
, narg
, c
);
802 print_number(ip
, narg
, c
);
812 print_number(ip
, narg
, c
);
820 print_number(ip
, narg
, c
);
827 print_number(ip
, narg
, c
);
828 print_number(ip
, narg
, c
);
830 getfsstatflagsname(*ip
);
835 print_number(ip
, narg
, c
);
836 print_number(ip
, narg
, c
);
843 print_number(ip
, narg
, c
);
851 print_number(ip
, narg
, c
);
852 print_number(ip
, narg
, c
);
854 sendrecvflagsname(*ip
);
860 print_number(ip
, narg
, c
);
861 print_number(ip
, narg
, c
);
862 print_number(ip
, narg
, c
);
864 sendrecvflagsname(*ip
);
871 print_number(ip
, narg
, c
);
878 print_number(ip
, narg
, c
);
897 print_number(ip
, narg
, c
);
898 print_number(ip
, narg
, c
);
904 #ifdef SYS_freebsd6_mmap
905 case SYS_freebsd6_mmap
:
906 print_number(ip
, narg
, c
);
907 print_number(ip
, narg
, c
);
919 print_number(ip
, narg
, c
);
920 print_number(ip
, narg
, c
);
931 print_number(ip
, narg
, c
);
932 print_number(ip
, narg
, c
);
939 print_number(ip
, narg
, c
);
940 print_number(ip
, narg
, c
);
942 madvisebehavname(*ip
);
946 case SYS_setpriority
:
947 print_number(ip
, narg
, c
);
948 print_number(ip
, narg
, c
);
955 print_number(ip
, narg
, c
);
957 fcntlcmdname(ip
[0], ip
[1], decimal
);
965 sockdomainname(sockdomain
);
969 socktypenamewithflags(*ip
);
972 if (sockdomain
== PF_INET
||
973 sockdomain
== PF_INET6
) {
975 sockipprotoname(*ip
);
984 print_number(ip
, narg
, c
);
986 sockoptlevelname(*ip
, decimal
);
987 if (*ip
== SOL_SOCKET
) {
996 #ifdef SYS_freebsd6_lseek
997 case SYS_freebsd6_lseek
:
998 print_number(ip
, narg
, c
);
999 /* Hidden 'pad' argument, not in lseek(2) */
1000 print_number(ip
, narg
, c
);
1001 print_number(ip
, narg
, c
);
1009 print_number(ip
, narg
, c
);
1010 /* Hidden 'pad' argument, not in lseek(2) */
1011 print_number(ip
, narg
, c
);
1018 print_number(ip
, narg
, c
);
1028 print_number(ip
, narg
, c
);
1035 print_number(ip
, narg
, c
);
1037 shutdownhowname(*ip
);
1041 case SYS_socketpair
:
1043 sockdomainname(*ip
);
1047 socktypenamewithflags(*ip
);
1061 print_number(ip
, narg
, c
);
1083 print_number(ip
, narg
, c
);
1084 print_number(ip
, narg
, c
);
1091 print_number(ip
, narg
, c
);
1092 print_number(ip
, narg
, c
);
1099 print_number(ip
, narg
, c
);
1106 print_number(ip
, narg
, c
);
1107 print_number(ip
, narg
, c
);
1114 print_number(ip
, narg
, c
);
1121 print_number(ip
, narg
, c
);
1124 printf(",0%o", (unsigned int)ip
[1]);
1129 print_number(ip
, narg
, c
);
1130 print_number(ip
, narg
, c
);
1143 case SYS_lio_listio
:
1145 lio_listioname(*ip
);
1156 case SYS_sched_setscheduler
:
1157 print_number(ip
, narg
, c
);
1159 schedpolicyname(*ip
);
1163 case SYS_sched_get_priority_max
:
1164 case SYS_sched_get_priority_min
:
1166 schedpolicyname(*ip
);
1171 print_number(ip
, narg
, c
);
1172 print_number(ip
, narg
, c
);
1173 print_number(ip
, narg
, c
);
1174 print_number(ip
, narg
, c
);
1175 print_number(ip
, narg
, c
);
1176 print_number(ip
, narg
, c
);
1178 sendfileflagsname(*(int *)ip
);
1183 print_number(ip
, narg
, c
);
1189 case SYS_sigprocmask
:
1191 sigprocmaskhowname(*ip
);
1196 case SYS___acl_get_file
:
1197 case SYS___acl_set_file
:
1198 case SYS___acl_get_fd
:
1199 case SYS___acl_set_fd
:
1200 case SYS___acl_delete_file
:
1201 case SYS___acl_delete_fd
:
1202 case SYS___acl_aclcheck_file
:
1203 case SYS___acl_aclcheck_fd
:
1204 case SYS___acl_get_link
:
1205 case SYS___acl_set_link
:
1206 case SYS___acl_delete_link
:
1207 case SYS___acl_aclcheck_link
:
1208 print_number(ip
, narg
, c
);
1221 case SYS_extattrctl
:
1222 print_number(ip
, narg
, c
);
1224 extattrctlname(*ip
);
1229 print_number(ip
, narg
, c
);
1230 print_number(ip
, narg
, c
);
1232 mountflagsname(*ip
);
1236 case SYS_thr_create
:
1237 print_number(ip
, narg
, c
);
1238 print_number(ip
, narg
, c
);
1240 thrcreateflagsname(*ip
);
1245 print_number(ip
, narg
, c
);
1251 case SYS_kldunloadf
:
1252 print_number(ip
, narg
, c
);
1254 kldunloadfflagsname(*ip
);
1261 print_number(ip
, narg
, c
);
1263 atfdname(*ip
, decimal
);
1267 case SYS_cap_fcntls_limit
:
1268 print_number(ip
, narg
, c
);
1275 case SYS_posix_fadvise
:
1276 print_number(ip
, narg
, c
);
1277 print_number(ip
, narg
, c
);
1278 print_number(ip
, narg
, c
);
1280 fadvisebehavname((int)*ip
);
1286 idtypename(*ip
, decimal
);
1290 print_number(ip
, narg
, c
);
1292 procctlcmdname(*ip
);
1297 print_number(ip
, narg
, c
);
1301 case UMTX_OP_CV_WAIT
:
1305 umtxcvwaitflags(*ip
);
1307 case UMTX_OP_RW_RDLOCK
:
1311 umtxrwlockflags(*ip
);
1319 print_number(ip
, narg
, c
);
1327 ktrsysret(struct ktr_sysret
*ktr
, u_int sv_flags
)
1329 register_t ret
= ktr
->ktr_retval
;
1330 int error
= ktr
->ktr_error
;
1332 syscallname(ktr
->ktr_code
, sv_flags
);
1337 printf("%ld", (long)ret
);
1338 if (ret
< 0 || ret
> 9)
1339 printf("/%#lx", (unsigned long)ret
);
1342 printf("%ld", (long)ret
);
1344 printf("%#lx", (unsigned long)ret
);
1346 } else if (error
== ERESTART
)
1348 else if (error
== EJUSTRETURN
)
1349 printf("JUSTRETURN");
1351 printf("-1 errno %d", sysdecode_freebsd_to_abi_errno(
1352 syscallabi(sv_flags
), error
));
1354 printf(" %s", strerror(ktr
->ktr_error
));
1360 ktrnamei(char *cp
, int len
)
1362 printf("\"%.*s\"\n", len
, cp
);
1366 hexdump(char *p
, int len
, int screenwidth
)
1374 i
= 13; /* base offset */
1375 i
+= (width
/ 2) + 1; /* spaces every second byte */
1376 i
+= (width
* 2); /* width of bytes */
1378 i
+= width
; /* each byte */
1380 } while (i
< screenwidth
);
1383 for (n
= 0; n
< len
; n
+= width
) {
1384 for (i
= n
; i
< n
+ width
; i
++) {
1385 if ((i
% width
) == 0) { /* beginning of line */
1386 printf(" 0x%04x", i
);
1392 printf("%02x", p
[i
] & 0xff);
1397 for (i
= n
; i
< n
+ width
; i
++) {
1400 if (p
[i
] >= ' ' && p
[i
] <= '~')
1407 if ((i
% width
) != 0)
1412 visdump(char *dp
, int datalen
, int screenwidth
)
1421 for (;datalen
> 0; datalen
--, dp
++) {
1422 vis(visbuf
, *dp
, VIS_CSTYLE
, *(dp
+1));
1425 * Keep track of printables and
1426 * space chars (like fold(1)).
1438 width
= 8 - (col
&07);
1443 if (col
+ width
> (screenwidth
-2)) {
1458 ktrgenio(struct ktr_genio
*ktr
, int len
)
1460 int datalen
= len
- sizeof (struct ktr_genio
);
1461 char *dp
= (char *)ktr
+ sizeof (struct ktr_genio
);
1462 static int screenwidth
= 0;
1465 printf("fd %d %s %d byte%s\n", ktr
->ktr_fd
,
1466 ktr
->ktr_rw
== UIO_READ
? "read" : "wrote", datalen
,
1467 datalen
== 1 ? "" : "s");
1470 if (screenwidth
== 0) {
1473 if (fancy
&& ioctl(fileno(stderr
), TIOCGWINSZ
, &ws
) != -1 &&
1475 screenwidth
= ws
.ws_col
;
1479 if (maxdata
&& datalen
> maxdata
)
1482 for (i
= 0, binary
= 0; i
< datalen
&& binary
== 0; i
++) {
1483 if (dp
[i
] >= 32 && dp
[i
] < 127)
1485 if (dp
[i
] == 10 || dp
[i
] == 13 || dp
[i
] == 0 || dp
[i
] == 9)
1490 hexdump(dp
, datalen
, screenwidth
);
1492 visdump(dp
, datalen
, screenwidth
);
1495 const char *signames
[] = {
1496 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */
1497 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */
1498 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */
1499 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */
1500 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */
1501 "USR2", NULL
, /* 31 - 32 */
1505 ktrpsig(struct ktr_psig
*psig
)
1507 if (psig
->signo
> 0 && psig
->signo
< NSIG
)
1508 printf("SIG%s ", signames
[psig
->signo
]);
1510 printf("SIG %d ", psig
->signo
);
1511 if (psig
->action
== SIG_DFL
) {
1512 printf("SIG_DFL code=");
1513 sigcodename(psig
->signo
, psig
->code
);
1516 printf("caught handler=0x%lx mask=0x%x code=",
1517 (u_long
)psig
->action
, psig
->mask
.__bits
[0]);
1518 sigcodename(psig
->signo
, psig
->code
);
1524 ktrcsw_old(struct ktr_csw_old
*cs
)
1526 printf("%s %s\n", cs
->out
? "stop" : "resume",
1527 cs
->user
? "user" : "kernel");
1531 ktrcsw(struct ktr_csw
*cs
)
1533 printf("%s %s \"%s\"\n", cs
->out
? "stop" : "resume",
1534 cs
->user
? "user" : "kernel", cs
->wmesg
);
1538 ktruser(int len
, void *p
)
1542 if (sysdecode_utrace(stdout
, p
, len
)) {
1551 printf(" %d", *cp
++);
1553 printf(" %02x", *cp
++);
1558 ktrcaprights(cap_rights_t
*rightsp
)
1561 printf("cap_rights_t ");
1567 ktrtimeval(struct timeval
*tv
)
1570 printf("{%ld, %ld}", (long)tv
->tv_sec
, tv
->tv_usec
);
1574 ktritimerval(struct itimerval
*it
)
1577 printf("itimerval { .interval = ");
1578 ktrtimeval(&it
->it_interval
);
1579 printf(", .value = ");
1580 ktrtimeval(&it
->it_value
);
1585 ktrsockaddr(struct sockaddr
*sa
)
1588 TODO: Support additional address families
1589 #include <netnatm/natm.h>
1590 struct sockaddr_natm *natm;
1591 #include <netsmb/netbios.h>
1592 struct sockaddr_nb *nb;
1597 * note: ktrstruct() has already verified that sa points to a
1598 * buffer at least sizeof(struct sockaddr) bytes long and exactly
1599 * sa->sa_len bytes long.
1601 printf("struct sockaddr { ");
1602 sockfamilyname(sa
->sa_family
);
1605 #define check_sockaddr_len(n) \
1606 if (sa_##n.s##n##_len < sizeof(struct sockaddr_##n)) { \
1607 printf("invalid"); \
1611 switch(sa
->sa_family
) {
1613 struct sockaddr_in sa_in
;
1615 memset(&sa_in
, 0, sizeof(sa_in
));
1616 memcpy(&sa_in
, sa
, sa
->sa_len
);
1617 check_sockaddr_len(in
);
1618 inet_ntop(AF_INET
, &sa_in
.sin_addr
, addr
, sizeof addr
);
1619 printf("%s:%u", addr
, ntohs(sa_in
.sin_port
));
1623 struct sockaddr_in6 sa_in6
;
1625 memset(&sa_in6
, 0, sizeof(sa_in6
));
1626 memcpy(&sa_in6
, sa
, sa
->sa_len
);
1627 check_sockaddr_len(in6
);
1628 getnameinfo((struct sockaddr
*)&sa_in6
, sizeof(sa_in6
),
1629 addr
, sizeof(addr
), NULL
, 0, NI_NUMERICHOST
);
1630 printf("[%s]:%u", addr
, htons(sa_in6
.sin6_port
));
1634 struct sockaddr_un sa_un
;
1636 memset(&sa_un
, 0, sizeof(sa_un
));
1637 memcpy(&sa_un
, sa
, sa
->sa_len
);
1638 printf("%.*s", (int)sizeof(sa_un
.sun_path
), sa_un
.sun_path
);
1642 printf("unknown address family");
1648 ktrstat(struct stat
*statp
)
1650 char mode
[12], timestr
[PATH_MAX
+ 4];
1656 * note: ktrstruct() has already verified that statp points to a
1657 * buffer exactly sizeof(struct stat) bytes long.
1659 printf("struct stat {");
1660 printf("dev=%ju, ino=%ju, ",
1661 (uintmax_t)statp
->st_dev
, (uintmax_t)statp
->st_ino
);
1663 printf("mode=0%jo, ", (uintmax_t)statp
->st_mode
);
1665 strmode(statp
->st_mode
, mode
);
1666 printf("mode=%s, ", mode
);
1668 printf("nlink=%ju, ", (uintmax_t)statp
->st_nlink
);
1672 #ifdef HAVE_LIBCASPER
1674 pwd
= cap_getpwuid(cappwd
, statp
->st_uid
);
1677 pwd
= getpwuid(statp
->st_uid
);
1680 printf("uid=%ju, ", (uintmax_t)statp
->st_uid
);
1682 printf("uid=\"%s\", ", pwd
->pw_name
);
1686 #ifdef HAVE_LIBCASPER
1688 grp
= cap_getgrgid(capgrp
, statp
->st_gid
);
1691 grp
= getgrgid(statp
->st_gid
);
1694 printf("gid=%ju, ", (uintmax_t)statp
->st_gid
);
1696 printf("gid=\"%s\", ", grp
->gr_name
);
1697 printf("rdev=%ju, ", (uintmax_t)statp
->st_rdev
);
1700 printf("%jd", (intmax_t)statp
->st_atim
.tv_sec
);
1702 tm
= localtime(&statp
->st_atim
.tv_sec
);
1703 strftime(timestr
, sizeof(timestr
), TIME_FORMAT
, tm
);
1704 printf("\"%s\"", timestr
);
1706 if (statp
->st_atim
.tv_nsec
!= 0)
1707 printf(".%09ld, ", statp
->st_atim
.tv_nsec
);
1712 printf("%jd", (intmax_t)statp
->st_mtim
.tv_sec
);
1714 tm
= localtime(&statp
->st_mtim
.tv_sec
);
1715 strftime(timestr
, sizeof(timestr
), TIME_FORMAT
, tm
);
1716 printf("\"%s\"", timestr
);
1718 if (statp
->st_mtim
.tv_nsec
!= 0)
1719 printf(".%09ld, ", statp
->st_mtim
.tv_nsec
);
1724 printf("%jd", (intmax_t)statp
->st_ctim
.tv_sec
);
1726 tm
= localtime(&statp
->st_ctim
.tv_sec
);
1727 strftime(timestr
, sizeof(timestr
), TIME_FORMAT
, tm
);
1728 printf("\"%s\"", timestr
);
1730 if (statp
->st_ctim
.tv_nsec
!= 0)
1731 printf(".%09ld, ", statp
->st_ctim
.tv_nsec
);
1734 printf("birthtime=");
1736 printf("%jd", (intmax_t)statp
->st_birthtim
.tv_sec
);
1738 tm
= localtime(&statp
->st_birthtim
.tv_sec
);
1739 strftime(timestr
, sizeof(timestr
), TIME_FORMAT
, tm
);
1740 printf("\"%s\"", timestr
);
1742 if (statp
->st_birthtim
.tv_nsec
!= 0)
1743 printf(".%09ld, ", statp
->st_birthtim
.tv_nsec
);
1746 printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
1747 (uintmax_t)statp
->st_size
, (uintmax_t)statp
->st_blksize
,
1748 (intmax_t)statp
->st_blocks
, statp
->st_flags
);
1753 ktrstruct(char *buf
, size_t buflen
)
1756 size_t namelen
, datalen
;
1758 cap_rights_t rights
;
1759 struct itimerval it
;
1761 struct sockaddr_storage ss
;
1763 for (name
= buf
, namelen
= 0;
1764 namelen
< buflen
&& name
[namelen
] != '\0';
1767 if (namelen
== buflen
)
1769 if (name
[namelen
] != '\0')
1771 data
= buf
+ namelen
+ 1;
1772 datalen
= buflen
- namelen
- 1;
1776 for (i
= 0; i
< (int)namelen
; ++i
)
1777 if (!isalpha(name
[i
]))
1779 if (strcmp(name
, "caprights") == 0) {
1780 if (datalen
!= sizeof(cap_rights_t
))
1782 memcpy(&rights
, data
, datalen
);
1783 ktrcaprights(&rights
);
1784 } else if (strcmp(name
, "itimerval") == 0) {
1785 if (datalen
!= sizeof(struct itimerval
))
1787 memcpy(&it
, data
, datalen
);
1789 } else if (strcmp(name
, "stat") == 0) {
1790 if (datalen
!= sizeof(struct stat
))
1792 memcpy(&sb
, data
, datalen
);
1794 } else if (strcmp(name
, "sockaddr") == 0) {
1795 if (datalen
> sizeof(ss
))
1797 memcpy(&ss
, data
, datalen
);
1798 if (datalen
!= ss
.ss_len
)
1800 ktrsockaddr((struct sockaddr
*)&ss
);
1802 printf("unknown structure\n");
1806 printf("invalid record\n");
1810 ktrcapfail(struct ktr_cap_fail
*ktr
)
1812 switch (ktr
->cap_type
) {
1813 case CAPFAIL_NOTCAPABLE
:
1814 /* operation on fd with insufficient capabilities */
1815 printf("operation requires ");
1816 capname(&ktr
->cap_needed
);
1817 printf(", descriptor holds ");
1818 capname(&ktr
->cap_held
);
1820 case CAPFAIL_INCREASE
:
1821 /* requested more capabilities than fd already has */
1822 printf("attempt to increase capabilities from ");
1823 capname(&ktr
->cap_held
);
1825 capname(&ktr
->cap_needed
);
1827 case CAPFAIL_SYSCALL
:
1828 /* called restricted syscall */
1829 printf("disallowed system call");
1831 case CAPFAIL_LOOKUP
:
1832 /* used ".." in strict-relative mode */
1833 printf("restricted VFS lookup");
1836 printf("unknown capability failure: ");
1837 capname(&ktr
->cap_needed
);
1839 capname(&ktr
->cap_held
);
1846 ktrfault(struct ktr_fault
*ktr
)
1849 printf("0x%jx ", (uintmax_t)ktr
->vaddr
);
1850 vmprotname(ktr
->type
);
1855 ktrfaultend(struct ktr_faultend
*ktr
)
1858 vmresultname(ktr
->result
);
1865 fprintf(stderr
, "usage: kdump [-dEnlHRrSsTA] [-f trfile] "
1866 "[-m maxdata] [-p pid] [-t trstr]\n");