1 /*- 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 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. 16 * 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. 28 * 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 $ 32 */ 33 34 #define _KERNEL_STRUCTURES 35 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" 52 53 extern const char *ioctlname(u_long); 54 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); 69 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; 75 76 #define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 77 78 int 79 main(int argc, char **argv) 80 { 81 int ch, col, ktrlen, size; 82 pid_t do_pid = -1; 83 void *m; 84 int trpoints = ALL_POINTS; 85 char *cp; 86 87 setlocale(LC_CTYPE, ""); 88 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(); 134 } 135 136 if (argc > optind) 137 usage(); 138 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; 157 } 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; 186 } 187 if (tail) 188 fflush(stdout); 189 } 190 exit(0); 191 } 192 193 static int 194 fread_tail(void *buf, int size, int num) 195 { 196 int i; 197 198 while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 199 sleep(1); 200 clearerr(stdin); 201 } 202 return (i); 203 } 204 205 static int 206 dumpheader(struct ktr_header *kth) 207 { 208 static char unknown[64]; 209 static struct timeval prevtime, temp; 210 const char *type; 211 int col; 212 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; 238 } 239 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; 252 } 253 col += printf("%ld.%06ld ", 254 kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); 255 } 256 col += printf("%s ", type); 257 return col; 258 } 259 260 #include <sys/syscall.h> 261 #define KTRACE 262 #include <kern/syscalls.c> 263 #undef KTRACE 264 int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 265 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", 270 }; 271 272 static void 273 ktrsyscall(struct ktr_syscall *ktr) 274 { 275 int narg = ktr->ktr_narg; 276 register_t *ip; 277 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) { 286 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); 296 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); 307 } 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--; 326 } 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--; 361 } 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--; 440 } 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 = ','; 779 } 780 } 781 while (narg > 0) { 782 print_number(ip,narg,c); 783 } 784 putchar(')'); 785 } 786 putchar('\n'); 787 } 788 789 static void 790 ktrsysret(struct ktr_sysret *ktr) 791 { 792 register_t ret = ktr->ktr_retval; 793 int error = ktr->ktr_error; 794 int code = ktr->ktr_code; 795 796 if (code >= nsyscalls || code < 0) 797 printf("[%d] ", code); 798 else 799 printf("%s ", syscallnames[code]); 800 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); 811 } 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)); 820 } 821 putchar('\n'); 822 } 823 824 static void 825 ktrnamei(char *cp, int len) 826 { 827 printf("\"%.*s\"\n", len, cp); 828 } 829 830 static void 831 ktrgenio(struct ktr_genio *ktr, int len) 832 { 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; 840 841 if (screenwidth == 0) { 842 struct winsize ws; 843 844 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 845 ws.ws_col > 8) 846 screenwidth = ws.ws_col; 847 else 848 screenwidth = 80; 849 } 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; 860 /* 861 * Keep track of printables and 862 * space chars (like fold(1)). 863 */ 864 if (col == 0) { 865 putchar('\t'); 866 col = 8; 867 } 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); 878 } 879 if (col + width > (screenwidth-2)) { 880 printf("\\\n\t"); 881 col = 8; 882 } 883 col += width; 884 do { 885 putchar(*cp++); 886 } while (*cp); 887 } 888 if (col == 0) 889 printf(" "); 890 printf("\"\n"); 891 } 892 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 */ 900 }; 901 902 static void 903 ktrpsig(struct ktr_psig *psig) 904 { 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); 911 } 912 913 static void 914 ktrcsw(struct ktr_csw *cs) 915 { 916 printf("%s %s\n", cs->out ? "stop" : "resume", 917 cs->user ? "user" : "kernel"); 918 } 919 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 930 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]; 939 }; 940 941 static void 942 ktruser_rtld(int len, unsigned char *p) 943 { 944 struct utrace_rtld *ut = (struct utrace_rtld *)p; 945 void *parent; 946 int mode; 947 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); 961 } 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"); 1018 } 1019 } 1020 1021 struct utrace_malloc { 1022 void *p; 1023 size_t s; 1024 void *r; 1025 }; 1026 1027 static void 1028 ktruser_malloc(int len __unused, unsigned char *p) 1029 { 1030 struct utrace_malloc *ut = (struct utrace_malloc *)p; 1031 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); 1042 } 1043 } 1044 1045 static void 1046 ktruser(int len, unsigned char *p) 1047 { 1048 1049 if (len >= 8 && bcmp(p, "RTLD", 4) == 0) { 1050 ktruser_rtld(len, p); 1051 return; 1052 } 1053 1054 if (len == sizeof(struct utrace_malloc)) { 1055 ktruser_malloc(len, p); 1056 return; 1057 } 1058 1059 printf("%d ", len); 1060 while (len--) 1061 printf(" %02x", *p++); 1062 printf("\n"); 1063 } 1064 1065 static void 1066 usage(void) 1067 { 1068 fprintf(stderr, 1069 "usage: kdump [-dnlRT] [-f trfile] [-m maxdata] [-t [cnisuw]] [-p pid]\n"); 1070 exit(1); 1071 } 1072 1073 static void 1074 timevalsub(struct timeval *t1, struct timeval *t2) 1075 { 1076 t1->tv_sec -= t2->tv_sec; 1077 t1->tv_usec -= t2->tv_usec; 1078 timevalfix(t1); 1079 } 1080 1081 static void 1082 timevalfix(struct timeval *t1) 1083 { 1084 if (t1->tv_usec < 0) { 1085 t1->tv_sec--; 1086 t1->tv_usec += 1000000; 1087 } 1088 if (t1->tv_usec >= 1000000) { 1089 t1->tv_sec++; 1090 t1->tv_usec -= 1000000; 1091 } 1092 } 1093