Merge branch 'vendor/DHCPCD'
[dragonfly.git] / usr.bin / kdump / kdump.c
blobad3a3aeaafb24bb8a13d5577607e24bde5c459dc
1 /*-
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
7 * are met:
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 * 3. 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
27 * SUCH DAMAGE.
29 * @(#) Copyright (c) 1988, 1993 The Regents of the University of California. All rights reserved.
30 * @(#)kdump.c 8.1 (Berkeley) 6/6/93
31 * $FreeBSD: src/usr.bin/kdump/kdump.c,v 1.29 2006/05/20 14:27:22 netchild Exp $
34 #define _KERNEL_STRUCTURES
36 #include <sys/errno.h>
37 #include <sys/param.h>
38 #include <sys/time.h>
39 #include <sys/ktrace.h>
40 #include <sys/ioctl.h>
41 #include <sys/ptrace.h>
42 #include <dlfcn.h>
43 #include <err.h>
44 #include <locale.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <unistd.h>
49 #include <vis.h>
50 #include "ktrace.h"
51 #include "kdump_subr.h"
53 extern const char *ioctlname(u_long);
55 static int dumpheader(struct ktr_header *);
56 static int fread_tail(void *, int, int);
57 static void ktrcsw(struct ktr_csw *);
58 static void ktrgenio(struct ktr_genio *, int);
59 static void ktrnamei(char *, int);
60 static void ktrpsig(struct ktr_psig *);
61 static void ktrsyscall(struct ktr_syscall *);
62 static void ktrsysret(struct ktr_sysret *);
63 static void ktruser(int, unsigned char *);
64 static void ktruser_malloc(int, unsigned char *);
65 static void ktruser_rtld(int, unsigned char *);
66 static void timevalfix(struct timeval *);
67 static void timevalsub(struct timeval *, struct timeval *);
68 static void usage(void);
70 int timestamp, decimal, fancy = 1, tail, maxdata = 64;
71 int fixedformat;
72 int cpustamp;
73 const char *tracefile = DEF_TRACEFILE;
74 struct ktr_header ktr_header;
76 #define eqs(s1, s2) (strcmp((s1), (s2)) == 0)
78 int
79 main(int argc, char **argv)
81 int ch, col, ktrlen, size;
82 pid_t do_pid = -1;
83 void *m;
84 int trpoints = ALL_POINTS;
85 char *cp;
87 setlocale(LC_CTYPE, "");
89 while ((ch = getopt(argc,argv,"acf:djlm:np:RTt:")) != -1)
90 switch((char)ch) {
91 case 'f':
92 tracefile = optarg;
93 break;
94 case 'j':
95 fixedformat = 1;
96 break;
97 case 'c':
98 cpustamp = 1;
99 break;
100 case 'a':
101 timestamp = 2; /* relative timestamp */
102 cpustamp = 1;
103 break;
104 case 'd':
105 decimal = 1;
106 break;
107 case 'l':
108 tail = 1;
109 break;
110 case 'm':
111 maxdata = atoi(optarg);
112 break;
113 case 'n':
114 fancy = 0;
115 break;
116 case 'p':
117 do_pid = strtoul(optarg, &cp, 0);
118 if (*cp != 0)
119 errx(1,"invalid number %s", optarg);
120 break;
121 case 'R':
122 timestamp = 2; /* relative timestamp */
123 break;
124 case 'T':
125 timestamp = 1;
126 break;
127 case 't':
128 trpoints = getpoints(optarg);
129 if (trpoints < 0)
130 errx(1, "unknown trace point in %s", optarg);
131 break;
132 default:
133 usage();
136 if (argc > optind)
137 usage();
139 m = (void *)malloc(size = 1025);
140 if (m == NULL)
141 errx(1, "%s", strerror(ENOMEM));
142 if (!freopen(tracefile, "r", stdin))
143 err(1, "%s", tracefile);
144 while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
145 if (trpoints & (1 << ktr_header.ktr_type) &&
146 (do_pid == -1 || ktr_header.ktr_pid == do_pid))
147 col = dumpheader(&ktr_header);
148 else
149 col = -1;
150 if ((ktrlen = ktr_header.ktr_len) < 0)
151 errx(1, "bogus length 0x%x", ktrlen);
152 if (ktrlen > size) {
153 m = (void *)realloc(m, ktrlen+1);
154 if (m == NULL)
155 errx(1, "%s", strerror(ENOMEM));
156 size = ktrlen;
158 if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
159 errx(1, "data too short");
160 if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
161 continue;
162 if (col == -1)
163 continue;
164 switch (ktr_header.ktr_type) {
165 case KTR_SYSCALL:
166 ktrsyscall((struct ktr_syscall *)m);
167 break;
168 case KTR_SYSRET:
169 ktrsysret((struct ktr_sysret *)m);
170 break;
171 case KTR_NAMEI:
172 ktrnamei(m, ktrlen);
173 break;
174 case KTR_GENIO:
175 ktrgenio((struct ktr_genio *)m, ktrlen);
176 break;
177 case KTR_PSIG:
178 ktrpsig((struct ktr_psig *)m);
179 break;
180 case KTR_CSW:
181 ktrcsw((struct ktr_csw *)m);
182 break;
183 case KTR_USER:
184 ktruser(ktrlen, m);
185 break;
187 if (tail)
188 fflush(stdout);
190 exit(0);
193 static int
194 fread_tail(void *buf, int size, int num)
196 int i;
198 while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
199 sleep(1);
200 clearerr(stdin);
202 return (i);
205 static int
206 dumpheader(struct ktr_header *kth)
208 static char unknown[64];
209 static struct timeval prevtime, temp;
210 const char *type;
211 int col;
213 switch (kth->ktr_type) {
214 case KTR_SYSCALL:
215 type = "CALL";
216 break;
217 case KTR_SYSRET:
218 type = "RET ";
219 break;
220 case KTR_NAMEI:
221 type = "NAMI";
222 break;
223 case KTR_GENIO:
224 type = "GIO ";
225 break;
226 case KTR_PSIG:
227 type = "PSIG";
228 break;
229 case KTR_CSW:
230 type = "CSW";
231 break;
232 case KTR_USER:
233 type = "USER";
234 break;
235 default:
236 sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
237 type = unknown;
240 if (kth->ktr_tid || (kth->ktr_flags & KTRH_THREADED) || fixedformat)
241 col = printf("%5d:%-4d", kth->ktr_pid, kth->ktr_tid);
242 else
243 col = printf("%5d", kth->ktr_pid);
244 if (cpustamp)
245 col += printf(" %2d", KTRH_CPUID_DECODE(kth->ktr_flags));
246 col += printf(" %-8.*s ", MAXCOMLEN, kth->ktr_comm);
247 if (timestamp) {
248 if (timestamp == 2) {
249 temp = kth->ktr_time;
250 timevalsub(&kth->ktr_time, &prevtime);
251 prevtime = temp;
253 col += printf("%ld.%06ld ",
254 kth->ktr_time.tv_sec, kth->ktr_time.tv_usec);
256 col += printf("%s ", type);
257 return col;
260 #include <sys/syscall.h>
261 #define KTRACE
262 #include <kern/syscalls.c>
263 #undef KTRACE
264 int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
266 static const char *ptrace_ops[] = {
267 "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U",
268 "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE",
269 "PT_KILL", "PT_STEP", "PT_ATTACH", "PT_DETACH",
272 static void
273 ktrsyscall(struct ktr_syscall *ktr)
275 int narg = ktr->ktr_narg;
276 register_t *ip;
278 if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0)
279 printf("[%d]", ktr->ktr_code);
280 else
281 printf("%s", syscallnames[ktr->ktr_code]);
282 ip = &ktr->ktr_args[0];
283 if (narg) {
284 char c = '(';
285 if (fancy) {
287 #define print_number(i,n,c) do { \
288 if (decimal) \
289 printf("%c%ld", c, (long)*i); \
290 else \
291 printf("%c%#lx", c, (long)*i); \
292 i++; \
293 n--; \
294 c = ','; \
295 } while (0);
297 if (ktr->ktr_code == SYS_ioctl) {
298 const char *cp;
299 print_number(ip,narg,c);
300 if ((cp = ioctlname(*ip)) != NULL)
301 printf(",%s", cp);
302 else {
303 if (decimal)
304 printf(",%ld", (long)*ip);
305 else
306 printf(",%#lx ", (long)*ip);
308 c = ',';
309 ip++;
310 narg--;
311 } else if (ktr->ktr_code == SYS_access ||
312 ktr->ktr_code == SYS_eaccess ||
313 ktr->ktr_code == SYS_faccessat) {
314 if (ktr->ktr_code == SYS_faccessat)
315 print_number(ip,narg,c);
316 print_number(ip,narg,c);
317 putchar(',');
318 accessmodename ((int)*ip);
319 ip++;
320 narg--;
321 if (ktr->ktr_code == SYS_faccessat) {
322 putchar(',');
323 atflagsname((int)*ip);
324 ip++;
325 narg--;
327 } else if (ktr->ktr_code == SYS_open ||
328 ktr->ktr_code == SYS_mq_open) {
329 int flags;
330 int mode;
331 print_number(ip,narg,c);
332 flags = *ip;
333 mode = *++ip;
334 putchar(',');
335 flagsandmodename (flags, mode, decimal);
336 ip++;
337 narg-=2;
338 } else if (ktr->ktr_code == SYS_wait4) {
339 print_number(ip,narg,c);
340 print_number(ip,narg,c);
341 putchar(',');
342 wait4optname ((int)*ip);
343 ip++;
344 narg--;
345 } else if (ktr->ktr_code == SYS_chmod ||
346 ktr->ktr_code == SYS_fchmod ||
347 ktr->ktr_code == SYS_fchmodat ||
348 ktr->ktr_code == SYS_lchmod) {
349 if (ktr->ktr_code == SYS_fchmodat)
350 print_number(ip,narg,c);
351 print_number(ip,narg,c);
352 putchar(',');
353 modename ((int)*ip);
354 ip++;
355 narg--;
356 if (ktr->ktr_code == SYS_fchmodat) {
357 putchar(',');
358 atflagsname((int)*ip);
359 ip++;
360 narg--;
362 } else if (ktr->ktr_code == SYS_fchownat ||
363 ktr->ktr_code == SYS_fstatat ||
364 ktr->ktr_code == SYS_linkat ||
365 ktr->ktr_code == SYS_unlinkat ||
366 ktr->ktr_code == SYS_utimensat) {
367 print_number(ip,narg,c);
368 print_number(ip,narg,c);
369 if (ktr->ktr_code != SYS_unlinkat)
370 print_number(ip,narg,c);
371 if (ktr->ktr_code == SYS_fchownat ||
372 ktr->ktr_code == SYS_linkat)
373 print_number(ip,narg,c);
374 putchar(',');
375 atflagsname((int)*ip);
376 ip++;
377 narg--;
378 } else if (ktr->ktr_code == SYS_mknod) {
379 print_number(ip,narg,c);
380 putchar(',');
381 modename ((int)*ip);
382 ip++;
383 narg--;
384 } else if (ktr->ktr_code == SYS_getfsstat ||
385 ktr->ktr_code == SYS_getvfsstat) {
386 print_number(ip,narg,c);
387 if (ktr->ktr_code == SYS_getvfsstat)
388 print_number(ip,narg,c);
389 print_number(ip,narg,c);
390 putchar(',');
391 getfsstatflagsname ((int)*ip);
392 ip++;
393 narg--;
394 } else if (ktr->ktr_code == SYS_mount) {
395 print_number(ip,narg,c);
396 print_number(ip,narg,c);
397 putchar(',');
398 mountflagsname ((int)*ip);
399 ip++;
400 narg--;
401 } else if (ktr->ktr_code == SYS_unmount) {
402 print_number(ip,narg,c);
403 putchar(',');
404 mountflagsname ((int)*ip);
405 ip++;
406 narg--;
407 } else if (ktr->ktr_code == SYS_recvmsg ||
408 ktr->ktr_code == SYS_sendmsg) {
409 print_number(ip,narg,c);
410 print_number(ip,narg,c);
411 putchar(',');
412 sendrecvflagsname ((int)*ip);
413 ip++;
414 narg--;
415 } else if (ktr->ktr_code == SYS_recvfrom ||
416 ktr->ktr_code == SYS_sendto) {
417 print_number(ip,narg,c);
418 print_number(ip,narg,c);
419 print_number(ip,narg,c);
420 putchar(',');
421 sendrecvflagsname ((int)*ip);
422 ip++;
423 narg--;
424 } else if (ktr->ktr_code == SYS_chflags ||
425 ktr->ktr_code == SYS_chflagsat ||
426 ktr->ktr_code == SYS_fchflags ||
427 ktr->ktr_code == SYS_lchflags) {
428 if (ktr->ktr_code == SYS_chflagsat)
429 print_number(ip,narg,c);
430 print_number(ip,narg,c);
431 putchar(',');
432 chflagsname((long)*ip);
433 ip++;
434 narg--;
435 if (ktr->ktr_code == SYS_chflagsat) {
436 putchar(',');
437 atflagsname((int)*ip);
438 ip++;
439 narg--;
441 } else if (ktr->ktr_code == SYS_kill) {
442 print_number(ip,narg,c);
443 putchar(',');
444 signame((int)*ip);
445 ip++;
446 narg--;
447 } else if (ktr->ktr_code == SYS_reboot) {
448 putchar('(');
449 rebootoptname((int)*ip);
450 ip++;
451 narg--;
452 } else if (ktr->ktr_code == SYS_umask) {
453 putchar('(');
454 modename((int)*ip);
455 ip++;
456 narg--;
457 } else if (ktr->ktr_code == SYS_msync) {
458 print_number(ip,narg,c);
459 print_number(ip,narg,c);
460 putchar(',');
461 msyncflagsname((int)*ip);
462 ip++;
463 narg--;
464 } else if (ktr->ktr_code == SYS_mmap) {
465 print_number(ip,narg,c);
466 print_number(ip,narg,c);
467 putchar(',');
468 mmapprotname ((int)*ip);
469 putchar(',');
470 ip++;
471 narg--;
472 mmapflagsname ((int)*ip);
473 ip++;
474 narg--;
475 } else if (ktr->ktr_code == SYS_mprotect) {
476 print_number(ip,narg,c);
477 print_number(ip,narg,c);
478 putchar(',');
479 mmapprotname ((int)*ip);
480 ip++;
481 narg--;
482 } else if (ktr->ktr_code == SYS_madvise) {
483 print_number(ip,narg,c);
484 print_number(ip,narg,c);
485 putchar(',');
486 madvisebehavname((int)*ip);
487 ip++;
488 narg--;
489 } else if (ktr->ktr_code == SYS_setpriority) {
490 putchar('(');
491 prioname((int)*ip);
492 ip++;
493 narg--;
494 c = ',';
495 print_number(ip,narg,c);
496 print_number(ip,narg,c);
497 } else if (ktr->ktr_code == SYS_fcntl) {
498 int cmd;
499 int arg;
500 print_number(ip,narg,c);
501 cmd = *ip;
502 arg = *++ip;
503 putchar(',');
504 fcntlcmdname(cmd, arg, decimal);
505 ip++;
506 narg-=2;
507 } else if (ktr->ktr_code == SYS_socket) {
508 putchar('(');
509 sockdomainname((int)*ip);
510 ip++;
511 narg--;
512 putchar(',');
513 socktypename((int)*ip);
514 ip++;
515 narg--;
516 c = ',';
517 } else if (ktr->ktr_code == SYS_setsockopt ||
518 ktr->ktr_code == SYS_getsockopt) {
519 print_number(ip,narg,c);
520 putchar(',');
521 sockoptlevelname((int)*ip, decimal);
522 ip++;
523 narg--;
524 putchar(',');
525 sockoptname((int)*ip);
526 ip++;
527 narg--;
528 } else if (ktr->ktr_code == SYS_lseek) {
529 print_number(ip,narg,c);
530 /* Hidden 'pad' argument, not in lseek(2) */
531 print_number(ip,narg,c);
532 print_number(ip,narg,c);
533 putchar(',');
534 whencename ((int)*ip);
535 ip++;
536 narg--;
537 } else if (ktr->ktr_code == SYS_flock) {
538 print_number(ip,narg,c);
539 putchar(',');
540 flockname((int)*ip);
541 ip++;
542 narg--;
543 } else if (ktr->ktr_code == SYS_mkfifo ||
544 ktr->ktr_code == SYS_mkdir) {
545 print_number(ip,narg,c);
546 putchar(',');
547 modename((int)*ip);
548 ip++;
549 narg--;
550 } else if (ktr->ktr_code == SYS_shutdown) {
551 print_number(ip,narg,c);
552 putchar(',');
553 shutdownhowname((int)*ip);
554 ip++;
555 narg--;
556 } else if (ktr->ktr_code == SYS_socketpair) {
557 putchar('(');
558 sockdomainname((int)*ip);
559 ip++;
560 narg--;
561 putchar(',');
562 socktypename((int)*ip);
563 ip++;
564 narg--;
565 c = ',';
566 } else if (ktr->ktr_code == SYS_getrlimit ||
567 ktr->ktr_code == SYS_setrlimit) {
568 putchar('(');
569 rlimitname((int)*ip);
570 ip++;
571 narg--;
572 c = ',';
573 } else if (ktr->ktr_code == SYS_quotactl) {
574 print_number(ip,narg,c);
575 quotactlname((int)*ip);
576 ip++;
577 narg--;
578 c = ',';
579 } else if (ktr->ktr_code == SYS_rtprio) {
580 putchar('(');
581 rtprioname((int)*ip);
582 ip++;
583 narg--;
584 c = ',';
585 } else if (ktr->ktr_code == SYS___semctl) {
586 print_number(ip,narg,c);
587 print_number(ip,narg,c);
588 semctlname((int)*ip);
589 ip++;
590 narg--;
591 } else if (ktr->ktr_code == SYS_semget) {
592 print_number(ip,narg,c);
593 print_number(ip,narg,c);
594 semgetname((int)*ip);
595 ip++;
596 narg--;
597 } else if (ktr->ktr_code == SYS_msgctl) {
598 print_number(ip,narg,c);
599 shmctlname((int)*ip);
600 ip++;
601 narg--;
602 } else if (ktr->ktr_code == SYS_shmat) {
603 print_number(ip,narg,c);
604 print_number(ip,narg,c);
605 shmatname((int)*ip);
606 ip++;
607 narg--;
608 } else if (ktr->ktr_code == SYS_shmctl) {
609 print_number(ip,narg,c);
610 shmctlname((int)*ip);
611 ip++;
612 narg--;
613 } else if (ktr->ktr_code == SYS_minherit) {
614 print_number(ip,narg,c);
615 print_number(ip,narg,c);
616 minheritname((int)*ip);
617 ip++;
618 narg--;
619 } else if (ktr->ktr_code == SYS_rfork) {
620 putchar('(');
621 rforkname((int)*ip);
622 ip++;
623 narg--;
624 c = ',';
625 } else if (ktr->ktr_code == SYS_lio_listio) {
626 putchar('(');
627 lio_listioname((int)*ip);
628 ip++;
629 narg--;
630 c = ',';
631 } else if (ktr->ktr_code == SYS_mlockall) {
632 putchar('(');
633 mlockallname((int)*ip);
634 ip++;
635 narg--;
636 } else if (ktr->ktr_code == SYS_sched_setscheduler) {
637 print_number(ip,narg,c);
638 schedpolicyname((int)*ip);
639 ip++;
640 narg--;
641 } else if (ktr->ktr_code == SYS_sched_get_priority_max ||
642 ktr->ktr_code == SYS_sched_get_priority_min) {
643 putchar('(');
644 schedpolicyname((int)*ip);
645 ip++;
646 narg--;
647 } else if (ktr->ktr_code == SYS_sendfile) {
648 print_number(ip,narg,c);
649 print_number(ip,narg,c);
650 print_number(ip,narg,c);
651 print_number(ip,narg,c);
652 print_number(ip,narg,c);
653 print_number(ip,narg,c);
654 sendfileflagsname((int)*ip);
655 ip++;
656 narg--;
657 } else if (ktr->ktr_code == SYS_kldsym) {
658 print_number(ip,narg,c);
659 kldsymcmdname((int)*ip);
660 ip++;
661 narg--;
662 } else if (ktr->ktr_code == SYS_sigprocmask) {
663 putchar('(');
664 sigprocmaskhowname((int)*ip);
665 ip++;
666 narg--;
667 c = ',';
668 } else if (ktr->ktr_code == SYS___acl_get_file ||
669 ktr->ktr_code == SYS___acl_set_file ||
670 ktr->ktr_code == SYS___acl_get_fd ||
671 ktr->ktr_code == SYS___acl_set_fd ||
672 ktr->ktr_code == SYS___acl_delete_file ||
673 ktr->ktr_code == SYS___acl_delete_fd ||
674 ktr->ktr_code == SYS___acl_aclcheck_file ||
675 ktr->ktr_code == SYS___acl_aclcheck_fd) {
676 print_number(ip,narg,c);
677 acltypename((int)*ip);
678 ip++;
679 narg--;
680 } else if (ktr->ktr_code == SYS_sigaction) {
681 putchar('(');
682 signame((int)*ip);
683 ip++;
684 narg--;
685 c = ',';
686 } else if (ktr->ktr_code == SYS_extattrctl) {
687 print_number(ip,narg,c);
688 extattrctlname((int)*ip);
689 ip++;
690 narg--;
691 } else if (ktr->ktr_code == SYS_ptrace) {
692 if (*ip < (register_t)NELEM(ptrace_ops) && *ip >= 0)
693 printf("(%s", ptrace_ops[*ip]);
694 #ifdef PT_GETREGS
695 else if (*ip == PT_GETREGS)
696 printf("(%s", "PT_GETREGS");
697 #endif
698 #ifdef PT_SETREGS
699 else if (*ip == PT_SETREGS)
700 printf("(%s", "PT_SETREGS");
701 #endif
702 #ifdef PT_GETFPREGS
703 else if (*ip == PT_GETFPREGS)
704 printf("(%s", "PT_GETFPREGS");
705 #endif
706 #ifdef PT_SETFPREGS
707 else if (*ip == PT_SETFPREGS)
708 printf("(%s", "PT_SETFPREGS");
709 #endif
710 #ifdef PT_GETDBREGS
711 else if (*ip == PT_GETDBREGS)
712 printf("(%s", "PT_GETDBREGS");
713 #endif
714 #ifdef PT_SETDBREGS
715 else if (*ip == PT_SETDBREGS)
716 printf("(%s", "PT_SETDBREGS");
717 #endif
718 else
719 printf("(%ld", (long)*ip);
720 c = ',';
721 ip++;
722 narg--;
723 } else if (ktr->ktr_code == SYS_clock_getres ||
724 ktr->ktr_code == SYS_clock_gettime ||
725 ktr->ktr_code == SYS_clock_settime) {
726 putchar('(');
727 clockidname((int)*ip);
728 ip++;
729 narg--;
730 c = ',';
731 } else if (ktr->ktr_code == SYS_fpathconf ||
732 ktr->ktr_code == SYS_lpathconf ||
733 ktr->ktr_code == SYS_pathconf) {
734 print_number(ip,narg,c);
735 putchar(',');
736 pathconfname((int)*ip);
737 ip++;
738 narg--;
739 } else if (ktr->ktr_code == SYS_kenv) {
740 putchar('(');
741 kenvactname((int)*ip);
742 ip++;
743 narg--;
744 c = ',';
745 } else if (ktr->ktr_code == SYS_usched_set) {
746 print_number(ip,narg,c);
747 putchar(',');
748 uschedcmdname((int)*ip);
749 ip++;
750 narg--;
751 } else if (ktr->ktr_code == SYS_sys_checkpoint) {
752 putchar('(');
753 ckpttypename((int)*ip);
754 ip++;
755 narg--;
756 c = ',';
757 } else if (ktr->ktr_code == SYS_procctl) {
758 print_number(ip,narg,c);
759 print_number(ip,narg,c);
760 putchar(',');
761 procctlcmdname((int)*ip);
762 ip++;
763 narg--;
764 c = ',';
765 } else if (ktr->ktr_code == SYS_mountctl) {
766 print_number(ip,narg,c);
767 putchar(',');
768 mountctlopname((int)*ip);
769 ip++;
770 narg--;
771 c = ',';
772 } else if (ktr->ktr_code == SYS_varsym_list ||
773 ktr->ktr_code == SYS_varsym_set) {
774 putchar('(');
775 varsymlvlname((int)*ip);
776 ip++;
777 narg--;
778 c = ',';
781 while (narg > 0) {
782 print_number(ip,narg,c);
784 putchar(')');
786 putchar('\n');
789 static void
790 ktrsysret(struct ktr_sysret *ktr)
792 register_t ret = ktr->ktr_retval;
793 int error = ktr->ktr_error;
794 int code = ktr->ktr_code;
796 if (code >= nsyscalls || code < 0)
797 printf("[%d] ", code);
798 else
799 printf("%s ", syscallnames[code]);
801 if (error == 0) {
802 if (fancy) {
803 printf("%ld", (long)ret);
804 if (ret < 0 || ret > 9)
805 printf("/%#lx", (long)ret);
806 } else {
807 if (decimal)
808 printf("%ld", (long)ret);
809 else
810 printf("%#lx", (long)ret);
812 } else if (error == ERESTART)
813 printf("RESTART");
814 else if (error == EJUSTRETURN)
815 printf("JUSTRETURN");
816 else {
817 printf("-1 errno %d", ktr->ktr_error);
818 if (fancy)
819 printf(" %s", strerror(ktr->ktr_error));
821 putchar('\n');
824 static void
825 ktrnamei(char *cp, int len)
827 printf("\"%.*s\"\n", len, cp);
830 static void
831 ktrgenio(struct ktr_genio *ktr, int len)
833 int datalen = len - sizeof (struct ktr_genio);
834 char *dp = (char *)ktr + sizeof (struct ktr_genio);
835 char *cp;
836 int col = 0;
837 int width;
838 char visbuf[5];
839 static int screenwidth = 0;
841 if (screenwidth == 0) {
842 struct winsize ws;
844 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
845 ws.ws_col > 8)
846 screenwidth = ws.ws_col;
847 else
848 screenwidth = 80;
850 printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
851 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
852 datalen == 1 ? "" : "s");
853 if (maxdata && datalen > maxdata)
854 datalen = maxdata;
855 printf(" \"");
856 col = 8;
857 for (;datalen > 0; datalen--, dp++) {
858 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
859 cp = visbuf;
861 * Keep track of printables and
862 * space chars (like fold(1)).
864 if (col == 0) {
865 putchar('\t');
866 col = 8;
868 switch(*cp) {
869 case '\n':
870 col = 0;
871 putchar('\n');
872 continue;
873 case '\t':
874 width = 8 - (col&07);
875 break;
876 default:
877 width = strlen(cp);
879 if (col + width > (screenwidth-2)) {
880 printf("\\\n\t");
881 col = 8;
883 col += width;
884 do {
885 putchar(*cp++);
886 } while (*cp);
888 if (col == 0)
889 printf(" ");
890 printf("\"\n");
893 const char *signames[NSIG] = {
894 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */
895 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */
896 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */
897 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */
898 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */
899 "USR2", NULL, /* 31 - 32 */
902 static void
903 ktrpsig(struct ktr_psig *psig)
905 printf("SIG%s ", signames[psig->signo]);
906 if (psig->action == SIG_DFL)
907 printf("SIG_DFL\n");
908 else
909 printf("caught handler=0x%lx mask=0x%x code=0x%x\n",
910 (u_long)psig->action, psig->mask.__bits[0], psig->code);
913 static void
914 ktrcsw(struct ktr_csw *cs)
916 printf("%s %s\n", cs->out ? "stop" : "resume",
917 cs->user ? "user" : "kernel");
920 #define UTRACE_DLOPEN_START 1
921 #define UTRACE_DLOPEN_STOP 2
922 #define UTRACE_DLCLOSE_START 3
923 #define UTRACE_DLCLOSE_STOP 4
924 #define UTRACE_LOAD_OBJECT 5
925 #define UTRACE_UNLOAD_OBJECT 6
926 #define UTRACE_ADD_RUNDEP 7
927 #define UTRACE_PRELOAD_FINISHED 8
928 #define UTRACE_INIT_CALL 9
929 #define UTRACE_FINI_CALL 10
931 struct utrace_rtld {
932 char sig[4]; /* 'RTLD' */
933 int event;
934 void *handle;
935 void *mapbase;
936 size_t mapsize;
937 int refcnt;
938 char name[MAXPATHLEN];
941 static void
942 ktruser_rtld(int len, unsigned char *p)
944 struct utrace_rtld *ut = (struct utrace_rtld *)p;
945 void *parent;
946 int mode;
948 switch (ut->event) {
949 case UTRACE_DLOPEN_START:
950 mode = ut->refcnt;
951 printf("dlopen(%s, ", ut->name);
952 switch (mode & RTLD_MODEMASK) {
953 case RTLD_NOW:
954 printf("RTLD_NOW");
955 break;
956 case RTLD_LAZY:
957 printf("RTLD_LAZY");
958 break;
959 default:
960 printf("%#x", mode & RTLD_MODEMASK);
962 if (mode & RTLD_GLOBAL)
963 printf(" | RTLD_GLOBAL");
964 if (mode & RTLD_TRACE)
965 printf(" | RTLD_TRACE");
966 if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
967 printf(" | %#x", mode &
968 ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
969 printf(")\n");
970 break;
971 case UTRACE_DLOPEN_STOP:
972 printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
973 ut->refcnt);
974 break;
975 case UTRACE_DLCLOSE_START:
976 printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
977 ut->refcnt);
978 break;
979 case UTRACE_DLCLOSE_STOP:
980 printf("dlclose(%p) finished\n", ut->handle);
981 break;
982 case UTRACE_LOAD_OBJECT:
983 printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle,
984 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
985 ut->name);
986 break;
987 case UTRACE_UNLOAD_OBJECT:
988 printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
989 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
990 ut->name);
991 break;
992 case UTRACE_ADD_RUNDEP:
993 parent = ut->mapbase;
994 printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
995 ut->handle, ut->name, ut->refcnt);
996 break;
997 case UTRACE_PRELOAD_FINISHED:
998 printf("RTLD: LD_PRELOAD finished\n");
999 break;
1000 case UTRACE_INIT_CALL:
1001 printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
1002 ut->name);
1003 break;
1004 case UTRACE_FINI_CALL:
1005 printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
1006 ut->name);
1007 break;
1008 default:
1009 p += 4;
1010 len -= 4;
1011 printf("RTLD: %d ", len);
1012 while (len--)
1013 if (decimal)
1014 printf(" %d", *p++);
1015 else
1016 printf(" %02x", *p++);
1017 printf("\n");
1021 struct utrace_malloc {
1022 void *p;
1023 size_t s;
1024 void *r;
1027 static void
1028 ktruser_malloc(int len __unused, unsigned char *p)
1030 struct utrace_malloc *ut = (struct utrace_malloc *)p;
1032 if (ut->p == NULL) {
1033 if (ut->s == 0 && ut->r == NULL)
1034 printf("malloc_init()\n");
1035 else
1036 printf("%p = malloc(%zu)\n", ut->r, ut->s);
1037 } else {
1038 if (ut->s == 0)
1039 printf("free(%p)\n", ut->p);
1040 else
1041 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s);
1045 static void
1046 ktruser(int len, unsigned char *p)
1049 if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
1050 ktruser_rtld(len, p);
1051 return;
1054 if (len == sizeof(struct utrace_malloc)) {
1055 ktruser_malloc(len, p);
1056 return;
1059 printf("%d ", len);
1060 while (len--)
1061 printf(" %02x", *p++);
1062 printf("\n");
1065 static void
1066 usage(void)
1068 fprintf(stderr,
1069 "usage: kdump [-dnlRT] [-f trfile] [-m maxdata] [-t [cnisuw]] [-p pid]\n");
1070 exit(1);
1073 static void
1074 timevalsub(struct timeval *t1, struct timeval *t2)
1076 t1->tv_sec -= t2->tv_sec;
1077 t1->tv_usec -= t2->tv_usec;
1078 timevalfix(t1);
1081 static void
1082 timevalfix(struct timeval *t1)
1084 if (t1->tv_usec < 0) {
1085 t1->tv_sec--;
1086 t1->tv_usec += 1000000;
1088 if (t1->tv_usec >= 1000000) {
1089 t1->tv_sec++;
1090 t1->tv_usec -= 1000000;