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/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" 53 54 extern const char *ioctlname(u_long); 55 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); 70 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; 76 77 #define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 78 79 int 80 main(int argc, char **argv) 81 { 82 int ch, col, ktrlen, size; 83 pid_t do_pid = -1; 84 void *m; 85 int trpoints = ALL_POINTS; 86 char *cp; 87 88 setlocale(LC_CTYPE, ""); 89 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(); 135 } 136 137 if (argc > optind) 138 usage(); 139 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; 158 } 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; 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 default: 237 sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 238 type = unknown; 239 } 240 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; 253 } 254 col += printf("%ld.%06ld ", 255 kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); 256 } 257 col += printf("%s ", type); 258 return col; 259 } 260 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]); 266 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", 271 }; 272 273 static void 274 ktrsyscall(struct ktr_syscall *ktr) 275 { 276 int narg = ktr->ktr_narg; 277 register_t *ip; 278 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) { 287 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); 297 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); 308 } 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--; 327 } 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--; 362 } 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--; 441 } 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)(sizeof(ptrace_ops) / 694 sizeof(ptrace_ops[0])) && *ip >= 0) 695 printf("(%s", ptrace_ops[*ip]); 696 #ifdef PT_GETREGS 697 else if (*ip == PT_GETREGS) 698 printf("(%s", "PT_GETREGS"); 699 #endif 700 #ifdef PT_SETREGS 701 else if (*ip == PT_SETREGS) 702 printf("(%s", "PT_SETREGS"); 703 #endif 704 #ifdef PT_GETFPREGS 705 else if (*ip == PT_GETFPREGS) 706 printf("(%s", "PT_GETFPREGS"); 707 #endif 708 #ifdef PT_SETFPREGS 709 else if (*ip == PT_SETFPREGS) 710 printf("(%s", "PT_SETFPREGS"); 711 #endif 712 #ifdef PT_GETDBREGS 713 else if (*ip == PT_GETDBREGS) 714 printf("(%s", "PT_GETDBREGS"); 715 #endif 716 #ifdef PT_SETDBREGS 717 else if (*ip == PT_SETDBREGS) 718 printf("(%s", "PT_SETDBREGS"); 719 #endif 720 else 721 printf("(%ld", (long)*ip); 722 c = ','; 723 ip++; 724 narg--; 725 } else if (ktr->ktr_code == SYS_clock_getres || 726 ktr->ktr_code == SYS_clock_gettime || 727 ktr->ktr_code == SYS_clock_settime) { 728 putchar('('); 729 clockidname((int)*ip); 730 ip++; 731 narg--; 732 c = ','; 733 } else if (ktr->ktr_code == SYS_fpathconf || 734 ktr->ktr_code == SYS_lpathconf || 735 ktr->ktr_code == SYS_pathconf) { 736 print_number(ip,narg,c); 737 putchar(','); 738 pathconfname((int)*ip); 739 ip++; 740 narg--; 741 } else if (ktr->ktr_code == SYS_kenv) { 742 putchar('('); 743 kenvactname((int)*ip); 744 ip++; 745 narg--; 746 c = ','; 747 } else if (ktr->ktr_code == SYS_usched_set) { 748 print_number(ip,narg,c); 749 putchar(','); 750 uschedcmdname((int)*ip); 751 ip++; 752 narg--; 753 } else if (ktr->ktr_code == SYS_sys_checkpoint) { 754 putchar('('); 755 ckpttypename((int)*ip); 756 ip++; 757 narg--; 758 c = ','; 759 } else if (ktr->ktr_code == SYS_procctl) { 760 print_number(ip,narg,c); 761 print_number(ip,narg,c); 762 putchar(','); 763 procctlcmdname((int)*ip); 764 ip++; 765 narg--; 766 c = ','; 767 } else if (ktr->ktr_code == SYS_mountctl) { 768 print_number(ip,narg,c); 769 putchar(','); 770 mountctlopname((int)*ip); 771 ip++; 772 narg--; 773 c = ','; 774 } else if (ktr->ktr_code == SYS_varsym_list || 775 ktr->ktr_code == SYS_varsym_set) { 776 putchar('('); 777 varsymlvlname((int)*ip); 778 ip++; 779 narg--; 780 c = ','; 781 } 782 } 783 while (narg > 0) { 784 print_number(ip,narg,c); 785 } 786 putchar(')'); 787 } 788 putchar('\n'); 789 } 790 791 static void 792 ktrsysret(struct ktr_sysret *ktr) 793 { 794 register_t ret = ktr->ktr_retval; 795 int error = ktr->ktr_error; 796 int code = ktr->ktr_code; 797 798 if (code >= nsyscalls || code < 0) 799 printf("[%d] ", code); 800 else 801 printf("%s ", syscallnames[code]); 802 803 if (error == 0) { 804 if (fancy) { 805 printf("%ld", (long)ret); 806 if (ret < 0 || ret > 9) 807 printf("/%#lx", (long)ret); 808 } else { 809 if (decimal) 810 printf("%ld", (long)ret); 811 else 812 printf("%#lx", (long)ret); 813 } 814 } else if (error == ERESTART) 815 printf("RESTART"); 816 else if (error == EJUSTRETURN) 817 printf("JUSTRETURN"); 818 else { 819 printf("-1 errno %d", ktr->ktr_error); 820 if (fancy) 821 printf(" %s", strerror(ktr->ktr_error)); 822 } 823 putchar('\n'); 824 } 825 826 static void 827 ktrnamei(char *cp, int len) 828 { 829 printf("\"%.*s\"\n", len, cp); 830 } 831 832 static void 833 ktrgenio(struct ktr_genio *ktr, int len) 834 { 835 int datalen = len - sizeof (struct ktr_genio); 836 char *dp = (char *)ktr + sizeof (struct ktr_genio); 837 char *cp; 838 int col = 0; 839 int width; 840 char visbuf[5]; 841 static int screenwidth = 0; 842 843 if (screenwidth == 0) { 844 struct winsize ws; 845 846 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 847 ws.ws_col > 8) 848 screenwidth = ws.ws_col; 849 else 850 screenwidth = 80; 851 } 852 printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 853 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 854 datalen == 1 ? "" : "s"); 855 if (maxdata && datalen > maxdata) 856 datalen = maxdata; 857 printf(" \""); 858 col = 8; 859 for (;datalen > 0; datalen--, dp++) { 860 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 861 cp = visbuf; 862 /* 863 * Keep track of printables and 864 * space chars (like fold(1)). 865 */ 866 if (col == 0) { 867 putchar('\t'); 868 col = 8; 869 } 870 switch(*cp) { 871 case '\n': 872 col = 0; 873 putchar('\n'); 874 continue; 875 case '\t': 876 width = 8 - (col&07); 877 break; 878 default: 879 width = strlen(cp); 880 } 881 if (col + width > (screenwidth-2)) { 882 printf("\\\n\t"); 883 col = 8; 884 } 885 col += width; 886 do { 887 putchar(*cp++); 888 } while (*cp); 889 } 890 if (col == 0) 891 printf(" "); 892 printf("\"\n"); 893 } 894 895 const char *signames[NSIG] = { 896 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 897 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 898 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 899 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 900 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 901 "USR2", NULL, /* 31 - 32 */ 902 }; 903 904 static void 905 ktrpsig(struct ktr_psig *psig) 906 { 907 printf("SIG%s ", signames[psig->signo]); 908 if (psig->action == SIG_DFL) 909 printf("SIG_DFL\n"); 910 else 911 printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 912 (u_long)psig->action, psig->mask.__bits[0], psig->code); 913 } 914 915 static void 916 ktrcsw(struct ktr_csw *cs) 917 { 918 printf("%s %s\n", cs->out ? "stop" : "resume", 919 cs->user ? "user" : "kernel"); 920 } 921 922 #define UTRACE_DLOPEN_START 1 923 #define UTRACE_DLOPEN_STOP 2 924 #define UTRACE_DLCLOSE_START 3 925 #define UTRACE_DLCLOSE_STOP 4 926 #define UTRACE_LOAD_OBJECT 5 927 #define UTRACE_UNLOAD_OBJECT 6 928 #define UTRACE_ADD_RUNDEP 7 929 #define UTRACE_PRELOAD_FINISHED 8 930 #define UTRACE_INIT_CALL 9 931 #define UTRACE_FINI_CALL 10 932 933 struct utrace_rtld { 934 char sig[4]; /* 'RTLD' */ 935 int event; 936 void *handle; 937 void *mapbase; 938 size_t mapsize; 939 int refcnt; 940 char name[MAXPATHLEN]; 941 }; 942 943 static void 944 ktruser_rtld(int len, unsigned char *p) 945 { 946 struct utrace_rtld *ut = (struct utrace_rtld *)p; 947 void *parent; 948 int mode; 949 950 switch (ut->event) { 951 case UTRACE_DLOPEN_START: 952 mode = ut->refcnt; 953 printf("dlopen(%s, ", ut->name); 954 switch (mode & RTLD_MODEMASK) { 955 case RTLD_NOW: 956 printf("RTLD_NOW"); 957 break; 958 case RTLD_LAZY: 959 printf("RTLD_LAZY"); 960 break; 961 default: 962 printf("%#x", mode & RTLD_MODEMASK); 963 } 964 if (mode & RTLD_GLOBAL) 965 printf(" | RTLD_GLOBAL"); 966 if (mode & RTLD_TRACE) 967 printf(" | RTLD_TRACE"); 968 if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)) 969 printf(" | %#x", mode & 970 ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)); 971 printf(")\n"); 972 break; 973 case UTRACE_DLOPEN_STOP: 974 printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name, 975 ut->refcnt); 976 break; 977 case UTRACE_DLCLOSE_START: 978 printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name, 979 ut->refcnt); 980 break; 981 case UTRACE_DLCLOSE_STOP: 982 printf("dlclose(%p) finished\n", ut->handle); 983 break; 984 case UTRACE_LOAD_OBJECT: 985 printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle, 986 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 987 ut->name); 988 break; 989 case UTRACE_UNLOAD_OBJECT: 990 printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle, 991 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 992 ut->name); 993 break; 994 case UTRACE_ADD_RUNDEP: 995 parent = ut->mapbase; 996 printf("RTLD: %p now depends on %p (%s, %d)\n", parent, 997 ut->handle, ut->name, ut->refcnt); 998 break; 999 case UTRACE_PRELOAD_FINISHED: 1000 printf("RTLD: LD_PRELOAD finished\n"); 1001 break; 1002 case UTRACE_INIT_CALL: 1003 printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle, 1004 ut->name); 1005 break; 1006 case UTRACE_FINI_CALL: 1007 printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle, 1008 ut->name); 1009 break; 1010 default: 1011 p += 4; 1012 len -= 4; 1013 printf("RTLD: %d ", len); 1014 while (len--) 1015 if (decimal) 1016 printf(" %d", *p++); 1017 else 1018 printf(" %02x", *p++); 1019 printf("\n"); 1020 } 1021 } 1022 1023 struct utrace_malloc { 1024 void *p; 1025 size_t s; 1026 void *r; 1027 }; 1028 1029 static void 1030 ktruser_malloc(int len __unused, unsigned char *p) 1031 { 1032 struct utrace_malloc *ut = (struct utrace_malloc *)p; 1033 1034 if (ut->p == NULL) { 1035 if (ut->s == 0 && ut->r == NULL) 1036 printf("malloc_init()\n"); 1037 else 1038 printf("%p = malloc(%zu)\n", ut->r, ut->s); 1039 } else { 1040 if (ut->s == 0) 1041 printf("free(%p)\n", ut->p); 1042 else 1043 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); 1044 } 1045 } 1046 1047 static void 1048 ktruser(int len, unsigned char *p) 1049 { 1050 1051 if (len >= 8 && bcmp(p, "RTLD", 4) == 0) { 1052 ktruser_rtld(len, p); 1053 return; 1054 } 1055 1056 if (len == sizeof(struct utrace_malloc)) { 1057 ktruser_malloc(len, p); 1058 return; 1059 } 1060 1061 printf("%d ", len); 1062 while (len--) 1063 printf(" %02x", *p++); 1064 printf("\n"); 1065 } 1066 1067 static void 1068 usage(void) 1069 { 1070 fprintf(stderr, 1071 "usage: kdump [-dnlRT] [-f trfile] [-m maxdata] [-t [cnisuw]] [-p pid]\n"); 1072 exit(1); 1073 } 1074 1075 static void 1076 timevalsub(struct timeval *t1, struct timeval *t2) 1077 { 1078 t1->tv_sec -= t2->tv_sec; 1079 t1->tv_usec -= t2->tv_usec; 1080 timevalfix(t1); 1081 } 1082 1083 static void 1084 timevalfix(struct timeval *t1) 1085 { 1086 if (t1->tv_usec < 0) { 1087 t1->tv_sec--; 1088 t1->tv_usec += 1000000; 1089 } 1090 if (t1->tv_usec >= 1000000) { 1091 t1->tv_sec++; 1092 t1->tv_usec -= 1000000; 1093 } 1094 } 1095