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 case KTR_SYSCTL: 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; 187 } 188 if (tail) 189 fflush(stdout); 190 } 191 exit(0); 192 } 193 194 static int 195 fread_tail(void *buf, int size, int num) 196 { 197 int i; 198 199 while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 200 sleep(1); 201 clearerr(stdin); 202 } 203 return (i); 204 } 205 206 static int 207 dumpheader(struct ktr_header *kth) 208 { 209 static char unknown[64]; 210 static struct timeval prevtime, temp; 211 const char *type; 212 int col; 213 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 case KTR_SYSCTL: 237 type = "SCTL"; 238 break; 239 default: 240 sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 241 type = unknown; 242 } 243 244 if (kth->ktr_tid || (kth->ktr_flags & KTRH_THREADED) || fixedformat) 245 col = printf("%5d:%-4d", kth->ktr_pid, kth->ktr_tid); 246 else 247 col = printf("%5d", kth->ktr_pid); 248 if (cpustamp) 249 col += printf(" %2d", KTRH_CPUID_DECODE(kth->ktr_flags)); 250 col += printf(" %-8.*s ", MAXCOMLEN, kth->ktr_comm); 251 if (timestamp) { 252 if (timestamp == 2) { 253 temp = kth->ktr_time; 254 timevalsub(&kth->ktr_time, &prevtime); 255 prevtime = temp; 256 } 257 col += printf("%ld.%06ld ", 258 kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); 259 } 260 col += printf("%s ", type); 261 return col; 262 } 263 264 #include <sys/syscall.h> 265 #define KTRACE 266 #include <kern/syscalls.c> 267 #undef KTRACE 268 int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 269 270 static const char *ptrace_ops[] = { 271 "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U", 272 "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE", 273 "PT_KILL", "PT_STEP", "PT_ATTACH", "PT_DETACH", 274 }; 275 276 static void 277 ktrsyscall(struct ktr_syscall *ktr) 278 { 279 int narg = ktr->ktr_narg; 280 register_t *ip; 281 282 if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) 283 printf("[%d]", ktr->ktr_code); 284 else 285 printf("%s", syscallnames[ktr->ktr_code]); 286 ip = &ktr->ktr_args[0]; 287 if (narg) { 288 char c = '('; 289 if (fancy) { 290 291 #define print_number(i,n,c) do { \ 292 if (decimal) \ 293 printf("%c%ld", c, (long)*i); \ 294 else \ 295 printf("%c%#lx", c, (long)*i); \ 296 i++; \ 297 n--; \ 298 c = ','; \ 299 } while (0); 300 301 if (ktr->ktr_code == SYS_ioctl) { 302 const char *cp; 303 print_number(ip,narg,c); 304 if ((cp = ioctlname(*ip)) != NULL) 305 printf(",%s", cp); 306 else { 307 if (decimal) 308 printf(",%ld", (long)*ip); 309 else 310 printf(",%#lx ", (long)*ip); 311 } 312 c = ','; 313 ip++; 314 narg--; 315 } else if (ktr->ktr_code == SYS_access || 316 ktr->ktr_code == SYS_eaccess || 317 ktr->ktr_code == SYS_faccessat) { 318 if (ktr->ktr_code == SYS_faccessat) 319 print_number(ip,narg,c); 320 print_number(ip,narg,c); 321 putchar(','); 322 accessmodename ((int)*ip); 323 ip++; 324 narg--; 325 if (ktr->ktr_code == SYS_faccessat) { 326 putchar(','); 327 atflagsname((int)*ip); 328 ip++; 329 narg--; 330 } 331 } else if (ktr->ktr_code == SYS_open || 332 ktr->ktr_code == SYS_mq_open) { 333 int flags; 334 int mode; 335 print_number(ip,narg,c); 336 flags = *ip; 337 mode = *++ip; 338 putchar(','); 339 flagsandmodename (flags, mode, decimal); 340 ip++; 341 narg-=2; 342 } else if (ktr->ktr_code == SYS_wait4) { 343 print_number(ip,narg,c); 344 print_number(ip,narg,c); 345 putchar(','); 346 wait4optname ((int)*ip); 347 ip++; 348 narg--; 349 } else if (ktr->ktr_code == SYS_chmod || 350 ktr->ktr_code == SYS_fchmod || 351 ktr->ktr_code == SYS_fchmodat || 352 ktr->ktr_code == SYS_lchmod) { 353 if (ktr->ktr_code == SYS_fchmodat) 354 print_number(ip,narg,c); 355 print_number(ip,narg,c); 356 putchar(','); 357 modename ((int)*ip); 358 ip++; 359 narg--; 360 if (ktr->ktr_code == SYS_fchmodat) { 361 putchar(','); 362 atflagsname((int)*ip); 363 ip++; 364 narg--; 365 } 366 } else if (ktr->ktr_code == SYS_fchownat || 367 ktr->ktr_code == SYS_fstatat || 368 ktr->ktr_code == SYS_linkat || 369 ktr->ktr_code == SYS_unlinkat || 370 ktr->ktr_code == SYS_utimensat) { 371 print_number(ip,narg,c); 372 print_number(ip,narg,c); 373 if (ktr->ktr_code != SYS_unlinkat) 374 print_number(ip,narg,c); 375 if (ktr->ktr_code == SYS_fchownat || 376 ktr->ktr_code == SYS_linkat) 377 print_number(ip,narg,c); 378 putchar(','); 379 atflagsname((int)*ip); 380 ip++; 381 narg--; 382 } else if (ktr->ktr_code == SYS_mknod) { 383 print_number(ip,narg,c); 384 putchar(','); 385 modename ((int)*ip); 386 ip++; 387 narg--; 388 } else if (ktr->ktr_code == SYS_getfsstat || 389 ktr->ktr_code == SYS_getvfsstat) { 390 print_number(ip,narg,c); 391 if (ktr->ktr_code == SYS_getvfsstat) 392 print_number(ip,narg,c); 393 print_number(ip,narg,c); 394 putchar(','); 395 getfsstatflagsname ((int)*ip); 396 ip++; 397 narg--; 398 } else if (ktr->ktr_code == SYS_mount) { 399 print_number(ip,narg,c); 400 print_number(ip,narg,c); 401 putchar(','); 402 mountflagsname ((int)*ip); 403 ip++; 404 narg--; 405 } else if (ktr->ktr_code == SYS_unmount) { 406 print_number(ip,narg,c); 407 putchar(','); 408 mountflagsname ((int)*ip); 409 ip++; 410 narg--; 411 } else if (ktr->ktr_code == SYS_recvmsg || 412 ktr->ktr_code == SYS_sendmsg) { 413 print_number(ip,narg,c); 414 print_number(ip,narg,c); 415 putchar(','); 416 sendrecvflagsname ((int)*ip); 417 ip++; 418 narg--; 419 } else if (ktr->ktr_code == SYS_recvfrom || 420 ktr->ktr_code == SYS_sendto) { 421 print_number(ip,narg,c); 422 print_number(ip,narg,c); 423 print_number(ip,narg,c); 424 putchar(','); 425 sendrecvflagsname ((int)*ip); 426 ip++; 427 narg--; 428 } else if (ktr->ktr_code == SYS_chflags || 429 ktr->ktr_code == SYS_chflagsat || 430 ktr->ktr_code == SYS_fchflags || 431 ktr->ktr_code == SYS_lchflags) { 432 if (ktr->ktr_code == SYS_chflagsat) 433 print_number(ip,narg,c); 434 print_number(ip,narg,c); 435 putchar(','); 436 chflagsname((long)*ip); 437 ip++; 438 narg--; 439 if (ktr->ktr_code == SYS_chflagsat) { 440 putchar(','); 441 atflagsname((int)*ip); 442 ip++; 443 narg--; 444 } 445 } else if (ktr->ktr_code == SYS_kill) { 446 print_number(ip,narg,c); 447 putchar(','); 448 signame((int)*ip); 449 ip++; 450 narg--; 451 } else if (ktr->ktr_code == SYS_reboot) { 452 putchar('('); 453 rebootoptname((int)*ip); 454 ip++; 455 narg--; 456 } else if (ktr->ktr_code == SYS_umask) { 457 putchar('('); 458 modename((int)*ip); 459 ip++; 460 narg--; 461 } else if (ktr->ktr_code == SYS_msync) { 462 print_number(ip,narg,c); 463 print_number(ip,narg,c); 464 putchar(','); 465 msyncflagsname((int)*ip); 466 ip++; 467 narg--; 468 } else if (ktr->ktr_code == SYS_mmap) { 469 print_number(ip,narg,c); 470 print_number(ip,narg,c); 471 putchar(','); 472 mmapprotname ((int)*ip); 473 putchar(','); 474 ip++; 475 narg--; 476 mmapflagsname ((int)*ip); 477 ip++; 478 narg--; 479 } else if (ktr->ktr_code == SYS_mprotect) { 480 print_number(ip,narg,c); 481 print_number(ip,narg,c); 482 putchar(','); 483 mmapprotname ((int)*ip); 484 ip++; 485 narg--; 486 } else if (ktr->ktr_code == SYS_madvise) { 487 print_number(ip,narg,c); 488 print_number(ip,narg,c); 489 putchar(','); 490 madvisebehavname((int)*ip); 491 ip++; 492 narg--; 493 } else if (ktr->ktr_code == SYS_setpriority) { 494 putchar('('); 495 prioname((int)*ip); 496 ip++; 497 narg--; 498 c = ','; 499 print_number(ip,narg,c); 500 print_number(ip,narg,c); 501 } else if (ktr->ktr_code == SYS_fcntl) { 502 int cmd; 503 int arg; 504 print_number(ip,narg,c); 505 cmd = *ip; 506 arg = *++ip; 507 putchar(','); 508 fcntlcmdname(cmd, arg, decimal); 509 ip++; 510 narg-=2; 511 } else if (ktr->ktr_code == SYS_socket) { 512 putchar('('); 513 sockdomainname((int)*ip); 514 ip++; 515 narg--; 516 putchar(','); 517 socktypename((int)*ip); 518 ip++; 519 narg--; 520 c = ','; 521 } else if (ktr->ktr_code == SYS_setsockopt || 522 ktr->ktr_code == SYS_getsockopt) { 523 print_number(ip,narg,c); 524 putchar(','); 525 sockoptlevelname((int)*ip, decimal); 526 ip++; 527 narg--; 528 putchar(','); 529 sockoptname((int)*ip); 530 ip++; 531 narg--; 532 } else if (ktr->ktr_code == SYS_lseek) { 533 print_number(ip,narg,c); 534 /* Hidden 'pad' argument, not in lseek(2) */ 535 print_number(ip,narg,c); 536 print_number(ip,narg,c); 537 putchar(','); 538 whencename ((int)*ip); 539 ip++; 540 narg--; 541 } else if (ktr->ktr_code == SYS_flock) { 542 print_number(ip,narg,c); 543 putchar(','); 544 flockname((int)*ip); 545 ip++; 546 narg--; 547 } else if (ktr->ktr_code == SYS_mkfifo || 548 ktr->ktr_code == SYS_mkdir) { 549 print_number(ip,narg,c); 550 putchar(','); 551 modename((int)*ip); 552 ip++; 553 narg--; 554 } else if (ktr->ktr_code == SYS_shutdown) { 555 print_number(ip,narg,c); 556 putchar(','); 557 shutdownhowname((int)*ip); 558 ip++; 559 narg--; 560 } else if (ktr->ktr_code == SYS_socketpair) { 561 putchar('('); 562 sockdomainname((int)*ip); 563 ip++; 564 narg--; 565 putchar(','); 566 socktypename((int)*ip); 567 ip++; 568 narg--; 569 c = ','; 570 } else if (ktr->ktr_code == SYS_getrlimit || 571 ktr->ktr_code == SYS_setrlimit) { 572 putchar('('); 573 rlimitname((int)*ip); 574 ip++; 575 narg--; 576 c = ','; 577 } else if (ktr->ktr_code == SYS_quotactl) { 578 print_number(ip,narg,c); 579 quotactlname((int)*ip); 580 ip++; 581 narg--; 582 c = ','; 583 } else if (ktr->ktr_code == SYS_rtprio) { 584 putchar('('); 585 rtprioname((int)*ip); 586 ip++; 587 narg--; 588 c = ','; 589 } else if (ktr->ktr_code == SYS___semctl) { 590 print_number(ip,narg,c); 591 print_number(ip,narg,c); 592 semctlname((int)*ip); 593 ip++; 594 narg--; 595 } else if (ktr->ktr_code == SYS_semget) { 596 print_number(ip,narg,c); 597 print_number(ip,narg,c); 598 semgetname((int)*ip); 599 ip++; 600 narg--; 601 } else if (ktr->ktr_code == SYS_msgctl) { 602 print_number(ip,narg,c); 603 shmctlname((int)*ip); 604 ip++; 605 narg--; 606 } else if (ktr->ktr_code == SYS_shmat) { 607 print_number(ip,narg,c); 608 print_number(ip,narg,c); 609 shmatname((int)*ip); 610 ip++; 611 narg--; 612 } else if (ktr->ktr_code == SYS_shmctl) { 613 print_number(ip,narg,c); 614 shmctlname((int)*ip); 615 ip++; 616 narg--; 617 } else if (ktr->ktr_code == SYS_minherit) { 618 print_number(ip,narg,c); 619 print_number(ip,narg,c); 620 minheritname((int)*ip); 621 ip++; 622 narg--; 623 } else if (ktr->ktr_code == SYS_rfork) { 624 putchar('('); 625 rforkname((int)*ip); 626 ip++; 627 narg--; 628 c = ','; 629 } else if (ktr->ktr_code == SYS_lio_listio) { 630 putchar('('); 631 lio_listioname((int)*ip); 632 ip++; 633 narg--; 634 c = ','; 635 } else if (ktr->ktr_code == SYS_mlockall) { 636 putchar('('); 637 mlockallname((int)*ip); 638 ip++; 639 narg--; 640 } else if (ktr->ktr_code == SYS_sched_setscheduler) { 641 print_number(ip,narg,c); 642 schedpolicyname((int)*ip); 643 ip++; 644 narg--; 645 } else if (ktr->ktr_code == SYS_sched_get_priority_max || 646 ktr->ktr_code == SYS_sched_get_priority_min) { 647 putchar('('); 648 schedpolicyname((int)*ip); 649 ip++; 650 narg--; 651 } else if (ktr->ktr_code == SYS_sendfile) { 652 print_number(ip,narg,c); 653 print_number(ip,narg,c); 654 print_number(ip,narg,c); 655 print_number(ip,narg,c); 656 print_number(ip,narg,c); 657 print_number(ip,narg,c); 658 sendfileflagsname((int)*ip); 659 ip++; 660 narg--; 661 } else if (ktr->ktr_code == SYS_kldsym) { 662 print_number(ip,narg,c); 663 kldsymcmdname((int)*ip); 664 ip++; 665 narg--; 666 } else if (ktr->ktr_code == SYS_sigprocmask) { 667 putchar('('); 668 sigprocmaskhowname((int)*ip); 669 ip++; 670 narg--; 671 c = ','; 672 } else if (ktr->ktr_code == SYS___acl_get_file || 673 ktr->ktr_code == SYS___acl_set_file || 674 ktr->ktr_code == SYS___acl_get_fd || 675 ktr->ktr_code == SYS___acl_set_fd || 676 ktr->ktr_code == SYS___acl_delete_file || 677 ktr->ktr_code == SYS___acl_delete_fd || 678 ktr->ktr_code == SYS___acl_aclcheck_file || 679 ktr->ktr_code == SYS___acl_aclcheck_fd) { 680 print_number(ip,narg,c); 681 acltypename((int)*ip); 682 ip++; 683 narg--; 684 } else if (ktr->ktr_code == SYS_sigaction) { 685 putchar('('); 686 signame((int)*ip); 687 ip++; 688 narg--; 689 c = ','; 690 } else if (ktr->ktr_code == SYS_extattrctl) { 691 print_number(ip,narg,c); 692 extattrctlname((int)*ip); 693 ip++; 694 narg--; 695 } else if (ktr->ktr_code == SYS_ptrace) { 696 if (*ip < (register_t)NELEM(ptrace_ops) && *ip >= 0) 697 printf("(%s", ptrace_ops[*ip]); 698 #ifdef PT_GETREGS 699 else if (*ip == PT_GETREGS) 700 printf("(%s", "PT_GETREGS"); 701 #endif 702 #ifdef PT_SETREGS 703 else if (*ip == PT_SETREGS) 704 printf("(%s", "PT_SETREGS"); 705 #endif 706 #ifdef PT_GETFPREGS 707 else if (*ip == PT_GETFPREGS) 708 printf("(%s", "PT_GETFPREGS"); 709 #endif 710 #ifdef PT_SETFPREGS 711 else if (*ip == PT_SETFPREGS) 712 printf("(%s", "PT_SETFPREGS"); 713 #endif 714 #ifdef PT_GETDBREGS 715 else if (*ip == PT_GETDBREGS) 716 printf("(%s", "PT_GETDBREGS"); 717 #endif 718 #ifdef PT_SETDBREGS 719 else if (*ip == PT_SETDBREGS) 720 printf("(%s", "PT_SETDBREGS"); 721 #endif 722 else 723 printf("(%ld", (long)*ip); 724 c = ','; 725 ip++; 726 narg--; 727 } else if (ktr->ktr_code == SYS_clock_getres || 728 ktr->ktr_code == SYS_clock_gettime || 729 ktr->ktr_code == SYS_clock_settime) { 730 putchar('('); 731 clockidname((int)*ip); 732 ip++; 733 narg--; 734 c = ','; 735 } else if (ktr->ktr_code == SYS_fpathconf || 736 ktr->ktr_code == SYS_lpathconf || 737 ktr->ktr_code == SYS_pathconf) { 738 print_number(ip,narg,c); 739 putchar(','); 740 pathconfname((int)*ip); 741 ip++; 742 narg--; 743 } else if (ktr->ktr_code == SYS_kenv) { 744 putchar('('); 745 kenvactname((int)*ip); 746 ip++; 747 narg--; 748 c = ','; 749 } else if (ktr->ktr_code == SYS_usched_set) { 750 print_number(ip,narg,c); 751 putchar(','); 752 uschedcmdname((int)*ip); 753 ip++; 754 narg--; 755 } else if (ktr->ktr_code == SYS_sys_checkpoint) { 756 putchar('('); 757 ckpttypename((int)*ip); 758 ip++; 759 narg--; 760 c = ','; 761 } else if (ktr->ktr_code == SYS_procctl) { 762 print_number(ip,narg,c); 763 print_number(ip,narg,c); 764 putchar(','); 765 procctlcmdname((int)*ip); 766 ip++; 767 narg--; 768 c = ','; 769 } else if (ktr->ktr_code == SYS_mountctl) { 770 print_number(ip,narg,c); 771 putchar(','); 772 mountctlopname((int)*ip); 773 ip++; 774 narg--; 775 c = ','; 776 } else if (ktr->ktr_code == SYS_varsym_list || 777 ktr->ktr_code == SYS_varsym_set) { 778 putchar('('); 779 varsymlvlname((int)*ip); 780 ip++; 781 narg--; 782 c = ','; 783 } 784 } 785 while (narg > 0) { 786 print_number(ip,narg,c); 787 } 788 putchar(')'); 789 } 790 putchar('\n'); 791 } 792 793 static void 794 ktrsysret(struct ktr_sysret *ktr) 795 { 796 register_t ret = ktr->ktr_retval; 797 int error = ktr->ktr_error; 798 int code = ktr->ktr_code; 799 800 if (code >= nsyscalls || code < 0) 801 printf("[%d] ", code); 802 else 803 printf("%s ", syscallnames[code]); 804 805 if (error == 0) { 806 if (fancy) { 807 printf("%ld", (long)ret); 808 if (ret < 0 || ret > 9) 809 printf("/%#lx", (long)ret); 810 } else { 811 if (decimal) 812 printf("%ld", (long)ret); 813 else 814 printf("%#lx", (long)ret); 815 } 816 } else if (error == ERESTART) 817 printf("RESTART"); 818 else if (error == EJUSTRETURN) 819 printf("JUSTRETURN"); 820 else { 821 printf("-1 errno %d", ktr->ktr_error); 822 if (fancy) 823 printf(" %s", strerror(ktr->ktr_error)); 824 } 825 putchar('\n'); 826 } 827 828 static void 829 ktrnamei(char *cp, int len) 830 { 831 printf("\"%.*s\"\n", len, cp); 832 } 833 834 static void 835 ktrgenio(struct ktr_genio *ktr, int len) 836 { 837 int datalen = len - sizeof (struct ktr_genio); 838 char *dp = (char *)ktr + sizeof (struct ktr_genio); 839 char *cp; 840 int col = 0; 841 int width; 842 char visbuf[5]; 843 static int screenwidth = 0; 844 845 if (screenwidth == 0) { 846 struct winsize ws; 847 848 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 849 ws.ws_col > 8) 850 screenwidth = ws.ws_col; 851 else 852 screenwidth = 80; 853 } 854 printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 855 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 856 datalen == 1 ? "" : "s"); 857 if (maxdata && datalen > maxdata) 858 datalen = maxdata; 859 printf(" \""); 860 col = 8; 861 for (;datalen > 0; datalen--, dp++) { 862 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 863 cp = visbuf; 864 /* 865 * Keep track of printables and 866 * space chars (like fold(1)). 867 */ 868 if (col == 0) { 869 putchar('\t'); 870 col = 8; 871 } 872 switch(*cp) { 873 case '\n': 874 col = 0; 875 putchar('\n'); 876 continue; 877 case '\t': 878 width = 8 - (col&07); 879 break; 880 default: 881 width = strlen(cp); 882 } 883 if (col + width > (screenwidth-2)) { 884 printf("\\\n\t"); 885 col = 8; 886 } 887 col += width; 888 do { 889 putchar(*cp++); 890 } while (*cp); 891 } 892 if (col == 0) 893 printf(" "); 894 printf("\"\n"); 895 } 896 897 const char *signames[NSIG] = { 898 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 899 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 900 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 901 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 902 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 903 "USR2", NULL, /* 31 - 32 */ 904 }; 905 906 static void 907 ktrpsig(struct ktr_psig *psig) 908 { 909 printf("SIG%s ", signames[psig->signo]); 910 if (psig->action == SIG_DFL) 911 printf("SIG_DFL\n"); 912 else 913 printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 914 (u_long)psig->action, psig->mask.__bits[0], psig->code); 915 } 916 917 static void 918 ktrcsw(struct ktr_csw *cs) 919 { 920 printf("%s %s\n", cs->out ? "stop" : "resume", 921 cs->user ? "user" : "kernel"); 922 } 923 924 #define UTRACE_DLOPEN_START 1 925 #define UTRACE_DLOPEN_STOP 2 926 #define UTRACE_DLCLOSE_START 3 927 #define UTRACE_DLCLOSE_STOP 4 928 #define UTRACE_LOAD_OBJECT 5 929 #define UTRACE_UNLOAD_OBJECT 6 930 #define UTRACE_ADD_RUNDEP 7 931 #define UTRACE_PRELOAD_FINISHED 8 932 #define UTRACE_INIT_CALL 9 933 #define UTRACE_FINI_CALL 10 934 935 struct utrace_rtld { 936 char sig[4]; /* 'RTLD' */ 937 int event; 938 void *handle; 939 void *mapbase; 940 size_t mapsize; 941 int refcnt; 942 char name[MAXPATHLEN]; 943 }; 944 945 static void 946 ktruser_rtld(int len, unsigned char *p) 947 { 948 struct utrace_rtld *ut = (struct utrace_rtld *)p; 949 void *parent; 950 int mode; 951 952 switch (ut->event) { 953 case UTRACE_DLOPEN_START: 954 mode = ut->refcnt; 955 printf("dlopen(%s, ", ut->name); 956 switch (mode & RTLD_MODEMASK) { 957 case RTLD_NOW: 958 printf("RTLD_NOW"); 959 break; 960 case RTLD_LAZY: 961 printf("RTLD_LAZY"); 962 break; 963 default: 964 printf("%#x", mode & RTLD_MODEMASK); 965 } 966 if (mode & RTLD_GLOBAL) 967 printf(" | RTLD_GLOBAL"); 968 if (mode & RTLD_TRACE) 969 printf(" | RTLD_TRACE"); 970 if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)) 971 printf(" | %#x", mode & 972 ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)); 973 printf(")\n"); 974 break; 975 case UTRACE_DLOPEN_STOP: 976 printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name, 977 ut->refcnt); 978 break; 979 case UTRACE_DLCLOSE_START: 980 printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name, 981 ut->refcnt); 982 break; 983 case UTRACE_DLCLOSE_STOP: 984 printf("dlclose(%p) finished\n", ut->handle); 985 break; 986 case UTRACE_LOAD_OBJECT: 987 printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle, 988 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 989 ut->name); 990 break; 991 case UTRACE_UNLOAD_OBJECT: 992 printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle, 993 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 994 ut->name); 995 break; 996 case UTRACE_ADD_RUNDEP: 997 parent = ut->mapbase; 998 printf("RTLD: %p now depends on %p (%s, %d)\n", parent, 999 ut->handle, ut->name, ut->refcnt); 1000 break; 1001 case UTRACE_PRELOAD_FINISHED: 1002 printf("RTLD: LD_PRELOAD finished\n"); 1003 break; 1004 case UTRACE_INIT_CALL: 1005 printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle, 1006 ut->name); 1007 break; 1008 case UTRACE_FINI_CALL: 1009 printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle, 1010 ut->name); 1011 break; 1012 default: 1013 p += 4; 1014 len -= 4; 1015 printf("RTLD: %d ", len); 1016 while (len--) 1017 if (decimal) 1018 printf(" %d", *p++); 1019 else 1020 printf(" %02x", *p++); 1021 printf("\n"); 1022 } 1023 } 1024 1025 struct utrace_malloc { 1026 void *p; 1027 size_t s; 1028 void *r; 1029 }; 1030 1031 static void 1032 ktruser_malloc(int len __unused, unsigned char *p) 1033 { 1034 struct utrace_malloc *ut = (struct utrace_malloc *)p; 1035 1036 if (ut->p == NULL) { 1037 if (ut->s == 0 && ut->r == NULL) 1038 printf("malloc_init()\n"); 1039 else 1040 printf("%p = malloc(%zu)\n", ut->r, ut->s); 1041 } else { 1042 if (ut->s == 0) 1043 printf("free(%p)\n", ut->p); 1044 else 1045 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); 1046 } 1047 } 1048 1049 static void 1050 ktruser(int len, unsigned char *p) 1051 { 1052 1053 if (len >= 8 && bcmp(p, "RTLD", 4) == 0) { 1054 ktruser_rtld(len, p); 1055 return; 1056 } 1057 1058 if (len == sizeof(struct utrace_malloc)) { 1059 ktruser_malloc(len, p); 1060 return; 1061 } 1062 1063 printf("%d ", len); 1064 while (len--) 1065 printf(" %02x", *p++); 1066 printf("\n"); 1067 } 1068 1069 static void 1070 usage(void) 1071 { 1072 fprintf(stderr, 1073 "usage: kdump [-dnlRT] [-f trfile] [-m maxdata] [-t [cnisuw]] [-p pid]\n"); 1074 exit(1); 1075 } 1076 1077 static void 1078 timevalsub(struct timeval *t1, struct timeval *t2) 1079 { 1080 t1->tv_sec -= t2->tv_sec; 1081 t1->tv_usec -= t2->tv_usec; 1082 timevalfix(t1); 1083 } 1084 1085 static void 1086 timevalfix(struct timeval *t1) 1087 { 1088 if (t1->tv_usec < 0) { 1089 t1->tv_sec--; 1090 t1->tv_usec += 1000000; 1091 } 1092 if (t1->tv_usec >= 1000000) { 1093 t1->tv_sec++; 1094 t1->tv_usec -= 1000000; 1095 } 1096 } 1097