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