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. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 static const char copyright[] = 36 "@(#) Copyright (c) 1988, 1993\n\ 37 The Regents of the University of California. All rights reserved.\n"; 38 #endif /* not lint */ 39 40 #ifndef lint 41 #if 0 42 static char sccsid[] = "@(#)kdump.c 8.1 (Berkeley) 6/6/93"; 43 #endif 44 #endif /* not lint */ 45 #include <sys/cdefs.h> 46 __FBSDID("$FreeBSD$"); 47 48 #define _KERNEL 49 extern int errno; 50 #include <sys/errno.h> 51 #undef _KERNEL 52 #include <sys/param.h> 53 #include <sys/errno.h> 54 #define _KERNEL 55 #include <sys/time.h> 56 #undef _KERNEL 57 #include <sys/uio.h> 58 #include <sys/ktrace.h> 59 #include <sys/ioctl.h> 60 #include <sys/socket.h> 61 #include <sys/stat.h> 62 #include <sys/un.h> 63 #ifdef IPX 64 #include <sys/types.h> 65 #include <netipx/ipx.h> 66 #endif 67 #ifdef NETATALK 68 #include <netatalk/at.h> 69 #endif 70 #include <arpa/inet.h> 71 #include <netinet/in.h> 72 #include <ctype.h> 73 #include <dlfcn.h> 74 #include <err.h> 75 #include <grp.h> 76 #include <inttypes.h> 77 #include <locale.h> 78 #include <pwd.h> 79 #include <stdio.h> 80 #include <stdlib.h> 81 #include <string.h> 82 #include <time.h> 83 #include <unistd.h> 84 #include <vis.h> 85 #include "ktrace.h" 86 #include "kdump_subr.h" 87 88 int fread_tail(void *, int, int); 89 void dumpheader(struct ktr_header *); 90 void ktrsyscall(struct ktr_syscall *); 91 void ktrsysret(struct ktr_sysret *); 92 void ktrnamei(char *, int); 93 void hexdump(char *, int, int); 94 void visdump(char *, int, int); 95 void ktrgenio(struct ktr_genio *, int); 96 void ktrpsig(struct ktr_psig *); 97 void ktrcsw(struct ktr_csw *); 98 void ktruser(int, unsigned char *); 99 void ktrsockaddr(struct sockaddr *); 100 void ktrstat(struct stat *); 101 void ktrstruct(char *, size_t); 102 void usage(void); 103 void sockfamilyname(int); 104 const char *ioctlname(u_long); 105 106 int timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata, 107 resolv = 0; 108 const char *tracefile = DEF_TRACEFILE; 109 struct ktr_header ktr_header; 110 111 #define TIME_FORMAT "%b %e %T %Y" 112 #define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 113 114 int 115 main(int argc, char *argv[]) 116 { 117 int ch, ktrlen, size; 118 void *m; 119 int trpoints = ALL_POINTS; 120 int drop_logged; 121 pid_t pid = 0; 122 123 (void) setlocale(LC_CTYPE, ""); 124 125 while ((ch = getopt(argc,argv,"f:dElm:np:HRrsTt:")) != -1) 126 switch((char)ch) { 127 case 'f': 128 tracefile = optarg; 129 break; 130 case 'd': 131 decimal = 1; 132 break; 133 case 'l': 134 tail = 1; 135 break; 136 case 'm': 137 maxdata = atoi(optarg); 138 break; 139 case 'n': 140 fancy = 0; 141 break; 142 case 'p': 143 pid = atoi(optarg); 144 break; 145 case 'r': 146 resolv = 1; 147 break; 148 case 's': 149 suppressdata = 1; 150 break; 151 case 'E': 152 timestamp = 3; /* elapsed timestamp */ 153 break; 154 case 'H': 155 threads = 1; 156 break; 157 case 'R': 158 timestamp = 2; /* relative timestamp */ 159 break; 160 case 'T': 161 timestamp = 1; 162 break; 163 case 't': 164 trpoints = getpoints(optarg); 165 if (trpoints < 0) 166 errx(1, "unknown trace point in %s", optarg); 167 break; 168 default: 169 usage(); 170 } 171 172 if (argc > optind) 173 usage(); 174 175 m = (void *)malloc(size = 1025); 176 if (m == NULL) 177 errx(1, "%s", strerror(ENOMEM)); 178 if (!freopen(tracefile, "r", stdin)) 179 err(1, "%s", tracefile); 180 drop_logged = 0; 181 while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 182 if (ktr_header.ktr_type & KTR_DROP) { 183 ktr_header.ktr_type &= ~KTR_DROP; 184 if (!drop_logged && threads) { 185 (void)printf( 186 "%6jd %6jd %-8.*s Events dropped.\n", 187 (intmax_t)ktr_header.ktr_pid, 188 ktr_header.ktr_tid > 0 ? 189 (intmax_t)ktr_header.ktr_tid : 0, 190 MAXCOMLEN, ktr_header.ktr_comm); 191 drop_logged = 1; 192 } else if (!drop_logged) { 193 (void)printf("%6jd %-8.*s Events dropped.\n", 194 (intmax_t)ktr_header.ktr_pid, MAXCOMLEN, 195 ktr_header.ktr_comm); 196 drop_logged = 1; 197 } 198 } 199 if (trpoints & (1<<ktr_header.ktr_type)) 200 if (pid == 0 || ktr_header.ktr_pid == pid) 201 dumpheader(&ktr_header); 202 if ((ktrlen = ktr_header.ktr_len) < 0) 203 errx(1, "bogus length 0x%x", ktrlen); 204 if (ktrlen > size) { 205 m = (void *)realloc(m, ktrlen+1); 206 if (m == NULL) 207 errx(1, "%s", strerror(ENOMEM)); 208 size = ktrlen; 209 } 210 if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 211 errx(1, "data too short"); 212 if (pid && ktr_header.ktr_pid != pid) 213 continue; 214 if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 215 continue; 216 drop_logged = 0; 217 switch (ktr_header.ktr_type) { 218 case KTR_SYSCALL: 219 ktrsyscall((struct ktr_syscall *)m); 220 break; 221 case KTR_SYSRET: 222 ktrsysret((struct ktr_sysret *)m); 223 break; 224 case KTR_NAMEI: 225 case KTR_SYSCTL: 226 ktrnamei(m, ktrlen); 227 break; 228 case KTR_GENIO: 229 ktrgenio((struct ktr_genio *)m, ktrlen); 230 break; 231 case KTR_PSIG: 232 ktrpsig((struct ktr_psig *)m); 233 break; 234 case KTR_CSW: 235 ktrcsw((struct ktr_csw *)m); 236 break; 237 case KTR_USER: 238 ktruser(ktrlen, m); 239 break; 240 case KTR_STRUCT: 241 ktrstruct(m, ktrlen); 242 break; 243 default: 244 printf("\n"); 245 break; 246 } 247 if (tail) 248 (void)fflush(stdout); 249 } 250 return 0; 251 } 252 253 int 254 fread_tail(void *buf, int size, int num) 255 { 256 int i; 257 258 while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 259 (void)sleep(1); 260 clearerr(stdin); 261 } 262 return (i); 263 } 264 265 void 266 dumpheader(struct ktr_header *kth) 267 { 268 static char unknown[64]; 269 static struct timeval prevtime, temp; 270 const char *type; 271 272 switch (kth->ktr_type) { 273 case KTR_SYSCALL: 274 type = "CALL"; 275 break; 276 case KTR_SYSRET: 277 type = "RET "; 278 break; 279 case KTR_NAMEI: 280 type = "NAMI"; 281 break; 282 case KTR_GENIO: 283 type = "GIO "; 284 break; 285 case KTR_PSIG: 286 type = "PSIG"; 287 break; 288 case KTR_CSW: 289 type = "CSW "; 290 break; 291 case KTR_USER: 292 type = "USER"; 293 break; 294 case KTR_STRUCT: 295 type = "STRU"; 296 break; 297 case KTR_SYSCTL: 298 type = "SCTL"; 299 break; 300 default: 301 (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 302 type = unknown; 303 } 304 305 /* 306 * The ktr_tid field was previously the ktr_buffer field, which held 307 * the kernel pointer value for the buffer associated with data 308 * following the record header. It now holds a threadid, but only 309 * for trace files after the change. Older trace files still contain 310 * kernel pointers. Detect this and suppress the results by printing 311 * negative tid's as 0. 312 */ 313 if (threads) 314 (void)printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid, 315 kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0, 316 MAXCOMLEN, kth->ktr_comm); 317 else 318 (void)printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN, 319 kth->ktr_comm); 320 if (timestamp) { 321 if (timestamp == 3) { 322 if (prevtime.tv_sec == 0) 323 prevtime = kth->ktr_time; 324 timevalsub(&kth->ktr_time, &prevtime); 325 } 326 if (timestamp == 2) { 327 temp = kth->ktr_time; 328 timevalsub(&kth->ktr_time, &prevtime); 329 prevtime = temp; 330 } 331 (void)printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec, 332 kth->ktr_time.tv_usec); 333 } 334 (void)printf("%s ", type); 335 } 336 337 #include <sys/syscall.h> 338 #define KTRACE 339 #include <sys/kern/syscalls.c> 340 #undef KTRACE 341 int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 342 343 void 344 ktrsyscall(struct ktr_syscall *ktr) 345 { 346 int narg = ktr->ktr_narg; 347 register_t *ip; 348 349 if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) 350 (void)printf("[%d]", ktr->ktr_code); 351 else 352 (void)printf("%s", syscallnames[ktr->ktr_code]); 353 ip = &ktr->ktr_args[0]; 354 if (narg) { 355 char c = '('; 356 if (fancy) { 357 358 #define print_number(i,n,c) do { \ 359 if (decimal) \ 360 (void)printf("%c%ld", c, (long)*i); \ 361 else \ 362 (void)printf("%c%#lx", c, (long)*i); \ 363 i++; \ 364 n--; \ 365 c = ','; \ 366 } while (0); 367 368 if (ktr->ktr_code == SYS_ioctl) { 369 const char *cp; 370 print_number(ip,narg,c); 371 if ((cp = ioctlname(*ip)) != NULL) 372 (void)printf(",%s", cp); 373 else { 374 if (decimal) 375 (void)printf(",%ld", (long)*ip); 376 else 377 (void)printf(",%#lx ", (long)*ip); 378 } 379 c = ','; 380 ip++; 381 narg--; 382 } else if (ktr->ktr_code == SYS_ptrace) { 383 (void)putchar('('); 384 ptraceopname ((int)*ip); 385 c = ','; 386 ip++; 387 narg--; 388 } else if (ktr->ktr_code == SYS_access || 389 ktr->ktr_code == SYS_eaccess) { 390 print_number(ip,narg,c); 391 (void)putchar(','); 392 accessmodename ((int)*ip); 393 ip++; 394 narg--; 395 } else if (ktr->ktr_code == SYS_open) { 396 int flags; 397 int mode; 398 print_number(ip,narg,c); 399 flags = *ip; 400 mode = *++ip; 401 (void)putchar(','); 402 flagsandmodename (flags, mode, decimal); 403 ip++; 404 narg-=2; 405 } else if (ktr->ktr_code == SYS_wait4) { 406 print_number(ip,narg,c); 407 print_number(ip,narg,c); 408 (void)putchar(','); 409 wait4optname ((int)*ip); 410 ip++; 411 narg--; 412 } else if (ktr->ktr_code == SYS_chmod || 413 ktr->ktr_code == SYS_fchmod || 414 ktr->ktr_code == SYS_lchmod) { 415 print_number(ip,narg,c); 416 (void)putchar(','); 417 modename ((int)*ip); 418 ip++; 419 narg--; 420 } else if (ktr->ktr_code == SYS_mknod) { 421 print_number(ip,narg,c); 422 (void)putchar(','); 423 modename ((int)*ip); 424 ip++; 425 narg--; 426 } else if (ktr->ktr_code == SYS_getfsstat) { 427 print_number(ip,narg,c); 428 print_number(ip,narg,c); 429 (void)putchar(','); 430 getfsstatflagsname ((int)*ip); 431 ip++; 432 narg--; 433 } else if (ktr->ktr_code == SYS_mount) { 434 print_number(ip,narg,c); 435 print_number(ip,narg,c); 436 (void)putchar(','); 437 mountflagsname ((int)*ip); 438 ip++; 439 narg--; 440 } else if (ktr->ktr_code == SYS_unmount) { 441 print_number(ip,narg,c); 442 (void)putchar(','); 443 mountflagsname ((int)*ip); 444 ip++; 445 narg--; 446 } else if (ktr->ktr_code == SYS_recvmsg || 447 ktr->ktr_code == SYS_sendmsg) { 448 print_number(ip,narg,c); 449 print_number(ip,narg,c); 450 (void)putchar(','); 451 sendrecvflagsname ((int)*ip); 452 ip++; 453 narg--; 454 } else if (ktr->ktr_code == SYS_recvfrom || 455 ktr->ktr_code == SYS_sendto) { 456 print_number(ip,narg,c); 457 print_number(ip,narg,c); 458 print_number(ip,narg,c); 459 (void)putchar(','); 460 sendrecvflagsname ((int)*ip); 461 ip++; 462 narg--; 463 } else if (ktr->ktr_code == SYS_chflags || 464 ktr->ktr_code == SYS_fchflags || 465 ktr->ktr_code == SYS_lchflags) { 466 print_number(ip,narg,c); 467 (void)putchar(','); 468 modename((int)*ip); 469 ip++; 470 narg--; 471 } else if (ktr->ktr_code == SYS_kill) { 472 print_number(ip,narg,c); 473 (void)putchar(','); 474 signame((int)*ip); 475 ip++; 476 narg--; 477 } else if (ktr->ktr_code == SYS_reboot) { 478 (void)putchar('('); 479 rebootoptname((int)*ip); 480 ip++; 481 narg--; 482 } else if (ktr->ktr_code == SYS_umask) { 483 (void)putchar('('); 484 modename((int)*ip); 485 ip++; 486 narg--; 487 } else if (ktr->ktr_code == SYS_msync) { 488 print_number(ip,narg,c); 489 print_number(ip,narg,c); 490 (void)putchar(','); 491 msyncflagsname((int)*ip); 492 ip++; 493 narg--; 494 #ifdef SYS_freebsd6_mmap 495 } else if (ktr->ktr_code == SYS_freebsd6_mmap) { 496 print_number(ip,narg,c); 497 print_number(ip,narg,c); 498 (void)putchar(','); 499 mmapprotname ((int)*ip); 500 (void)putchar(','); 501 ip++; 502 narg--; 503 mmapflagsname ((int)*ip); 504 ip++; 505 narg--; 506 #endif 507 } else if (ktr->ktr_code == SYS_mmap) { 508 print_number(ip,narg,c); 509 print_number(ip,narg,c); 510 (void)putchar(','); 511 mmapprotname ((int)*ip); 512 (void)putchar(','); 513 ip++; 514 narg--; 515 mmapflagsname ((int)*ip); 516 ip++; 517 narg--; 518 } else if (ktr->ktr_code == SYS_mprotect) { 519 print_number(ip,narg,c); 520 print_number(ip,narg,c); 521 (void)putchar(','); 522 mmapprotname ((int)*ip); 523 ip++; 524 narg--; 525 } else if (ktr->ktr_code == SYS_madvise) { 526 print_number(ip,narg,c); 527 print_number(ip,narg,c); 528 (void)putchar(','); 529 madvisebehavname((int)*ip); 530 ip++; 531 narg--; 532 } else if (ktr->ktr_code == SYS_setpriority) { 533 print_number(ip,narg,c); 534 print_number(ip,narg,c); 535 (void)putchar(','); 536 prioname((int)*ip); 537 ip++; 538 narg--; 539 } else if (ktr->ktr_code == SYS_fcntl) { 540 int cmd; 541 int arg; 542 print_number(ip,narg,c); 543 cmd = *ip; 544 arg = *++ip; 545 (void)putchar(','); 546 fcntlcmdname(cmd, arg, decimal); 547 ip++; 548 narg-=2; 549 } else if (ktr->ktr_code == SYS_socket) { 550 int sockdomain; 551 (void)putchar('('); 552 sockdomain=(int)*ip; 553 sockdomainname(sockdomain); 554 ip++; 555 narg--; 556 (void)putchar(','); 557 socktypename((int)*ip); 558 ip++; 559 narg--; 560 if (sockdomain == PF_INET || 561 sockdomain == PF_INET6) { 562 (void)putchar(','); 563 sockipprotoname((int)*ip); 564 ip++; 565 narg--; 566 } 567 c = ','; 568 } else if (ktr->ktr_code == SYS_setsockopt || 569 ktr->ktr_code == SYS_getsockopt) { 570 print_number(ip,narg,c); 571 (void)putchar(','); 572 sockoptlevelname((int)*ip, decimal); 573 if ((int)*ip == SOL_SOCKET) { 574 ip++; 575 narg--; 576 (void)putchar(','); 577 sockoptname((int)*ip); 578 } 579 ip++; 580 narg--; 581 #ifdef SYS_freebsd6_lseek 582 } else if (ktr->ktr_code == SYS_freebsd6_lseek) { 583 print_number(ip,narg,c); 584 /* Hidden 'pad' argument, not in lseek(2) */ 585 print_number(ip,narg,c); 586 print_number(ip,narg,c); 587 (void)putchar(','); 588 whencename ((int)*ip); 589 ip++; 590 narg--; 591 #endif 592 } else if (ktr->ktr_code == SYS_lseek) { 593 print_number(ip,narg,c); 594 /* Hidden 'pad' argument, not in lseek(2) */ 595 print_number(ip,narg,c); 596 (void)putchar(','); 597 whencename ((int)*ip); 598 ip++; 599 narg--; 600 601 } else if (ktr->ktr_code == SYS_flock) { 602 print_number(ip,narg,c); 603 (void)putchar(','); 604 flockname((int)*ip); 605 ip++; 606 narg--; 607 } else if (ktr->ktr_code == SYS_mkfifo || 608 ktr->ktr_code == SYS_mkdir) { 609 print_number(ip,narg,c); 610 (void)putchar(','); 611 modename((int)*ip); 612 ip++; 613 narg--; 614 } else if (ktr->ktr_code == SYS_shutdown) { 615 print_number(ip,narg,c); 616 (void)putchar(','); 617 shutdownhowname((int)*ip); 618 ip++; 619 narg--; 620 } else if (ktr->ktr_code == SYS_socketpair) { 621 (void)putchar('('); 622 sockdomainname((int)*ip); 623 ip++; 624 narg--; 625 (void)putchar(','); 626 socktypename((int)*ip); 627 ip++; 628 narg--; 629 c = ','; 630 } else if (ktr->ktr_code == SYS_getrlimit || 631 ktr->ktr_code == SYS_setrlimit) { 632 (void)putchar('('); 633 rlimitname((int)*ip); 634 ip++; 635 narg--; 636 c = ','; 637 } else if (ktr->ktr_code == SYS_quotactl) { 638 print_number(ip,narg,c); 639 (void)putchar(','); 640 quotactlname((int)*ip); 641 ip++; 642 narg--; 643 c = ','; 644 } else if (ktr->ktr_code == SYS_nfssvc) { 645 (void)putchar('('); 646 nfssvcname((int)*ip); 647 ip++; 648 narg--; 649 c = ','; 650 } else if (ktr->ktr_code == SYS_rtprio) { 651 (void)putchar('('); 652 rtprioname((int)*ip); 653 ip++; 654 narg--; 655 c = ','; 656 } else if (ktr->ktr_code == SYS___semctl) { 657 print_number(ip,narg,c); 658 print_number(ip,narg,c); 659 (void)putchar(','); 660 semctlname((int)*ip); 661 ip++; 662 narg--; 663 } else if (ktr->ktr_code == SYS_semget) { 664 print_number(ip,narg,c); 665 print_number(ip,narg,c); 666 (void)putchar(','); 667 semgetname((int)*ip); 668 ip++; 669 narg--; 670 } else if (ktr->ktr_code == SYS_msgctl) { 671 print_number(ip,narg,c); 672 (void)putchar(','); 673 shmctlname((int)*ip); 674 ip++; 675 narg--; 676 } else if (ktr->ktr_code == SYS_shmat) { 677 print_number(ip,narg,c); 678 print_number(ip,narg,c); 679 (void)putchar(','); 680 shmatname((int)*ip); 681 ip++; 682 narg--; 683 } else if (ktr->ktr_code == SYS_shmctl) { 684 print_number(ip,narg,c); 685 (void)putchar(','); 686 shmctlname((int)*ip); 687 ip++; 688 narg--; 689 } else if (ktr->ktr_code == SYS_minherit) { 690 print_number(ip,narg,c); 691 print_number(ip,narg,c); 692 (void)putchar(','); 693 minheritname((int)*ip); 694 ip++; 695 narg--; 696 } else if (ktr->ktr_code == SYS_rfork) { 697 (void)putchar('('); 698 rforkname((int)*ip); 699 ip++; 700 narg--; 701 c = ','; 702 } else if (ktr->ktr_code == SYS_lio_listio) { 703 (void)putchar('('); 704 lio_listioname((int)*ip); 705 ip++; 706 narg--; 707 c = ','; 708 } else if (ktr->ktr_code == SYS_mlockall) { 709 (void)putchar('('); 710 mlockallname((int)*ip); 711 ip++; 712 narg--; 713 } else if (ktr->ktr_code == SYS_sched_setscheduler) { 714 print_number(ip,narg,c); 715 (void)putchar(','); 716 schedpolicyname((int)*ip); 717 ip++; 718 narg--; 719 } else if (ktr->ktr_code == SYS_sched_get_priority_max || 720 ktr->ktr_code == SYS_sched_get_priority_min) { 721 (void)putchar('('); 722 schedpolicyname((int)*ip); 723 ip++; 724 narg--; 725 } else if (ktr->ktr_code == SYS_sendfile) { 726 print_number(ip,narg,c); 727 print_number(ip,narg,c); 728 print_number(ip,narg,c); 729 print_number(ip,narg,c); 730 print_number(ip,narg,c); 731 print_number(ip,narg,c); 732 (void)putchar(','); 733 sendfileflagsname((int)*ip); 734 ip++; 735 narg--; 736 } else if (ktr->ktr_code == SYS_kldsym) { 737 print_number(ip,narg,c); 738 (void)putchar(','); 739 kldsymcmdname((int)*ip); 740 ip++; 741 narg--; 742 } else if (ktr->ktr_code == SYS_sigprocmask) { 743 (void)putchar('('); 744 sigprocmaskhowname((int)*ip); 745 ip++; 746 narg--; 747 c = ','; 748 } else if (ktr->ktr_code == SYS___acl_get_file || 749 ktr->ktr_code == SYS___acl_set_file || 750 ktr->ktr_code == SYS___acl_get_fd || 751 ktr->ktr_code == SYS___acl_set_fd || 752 ktr->ktr_code == SYS___acl_delete_file || 753 ktr->ktr_code == SYS___acl_delete_fd || 754 ktr->ktr_code == SYS___acl_aclcheck_file || 755 ktr->ktr_code == SYS___acl_aclcheck_fd || 756 ktr->ktr_code == SYS___acl_get_link || 757 ktr->ktr_code == SYS___acl_set_link || 758 ktr->ktr_code == SYS___acl_delete_link || 759 ktr->ktr_code == SYS___acl_aclcheck_link) { 760 print_number(ip,narg,c); 761 (void)putchar(','); 762 acltypename((int)*ip); 763 ip++; 764 narg--; 765 } else if (ktr->ktr_code == SYS_sigaction) { 766 (void)putchar('('); 767 signame((int)*ip); 768 ip++; 769 narg--; 770 c = ','; 771 } else if (ktr->ktr_code == SYS_extattrctl) { 772 print_number(ip,narg,c); 773 (void)putchar(','); 774 extattrctlname((int)*ip); 775 ip++; 776 narg--; 777 } else if (ktr->ktr_code == SYS_nmount) { 778 print_number(ip,narg,c); 779 print_number(ip,narg,c); 780 (void)putchar(','); 781 mountflagsname ((int)*ip); 782 ip++; 783 narg--; 784 } else if (ktr->ktr_code == SYS_thr_create) { 785 print_number(ip,narg,c); 786 print_number(ip,narg,c); 787 (void)putchar(','); 788 thrcreateflagsname ((int)*ip); 789 ip++; 790 narg--; 791 } else if (ktr->ktr_code == SYS_thr_kill) { 792 print_number(ip,narg,c); 793 (void)putchar(','); 794 signame ((int)*ip); 795 ip++; 796 narg--; 797 } else if (ktr->ktr_code == SYS_kldunloadf) { 798 print_number(ip,narg,c); 799 (void)putchar(','); 800 kldunloadfflagsname ((int)*ip); 801 ip++; 802 narg--; 803 } 804 } 805 while (narg > 0) { 806 print_number(ip,narg,c); 807 } 808 (void)putchar(')'); 809 } 810 (void)putchar('\n'); 811 } 812 813 void 814 ktrsysret(struct ktr_sysret *ktr) 815 { 816 register_t ret = ktr->ktr_retval; 817 int error = ktr->ktr_error; 818 int code = ktr->ktr_code; 819 820 if (code >= nsyscalls || code < 0) 821 (void)printf("[%d] ", code); 822 else 823 (void)printf("%s ", syscallnames[code]); 824 825 if (error == 0) { 826 if (fancy) { 827 (void)printf("%ld", (long)ret); 828 if (ret < 0 || ret > 9) 829 (void)printf("/%#lx", (long)ret); 830 } else { 831 if (decimal) 832 (void)printf("%ld", (long)ret); 833 else 834 (void)printf("%#lx", (long)ret); 835 } 836 } else if (error == ERESTART) 837 (void)printf("RESTART"); 838 else if (error == EJUSTRETURN) 839 (void)printf("JUSTRETURN"); 840 else { 841 (void)printf("-1 errno %d", ktr->ktr_error); 842 if (fancy) 843 (void)printf(" %s", strerror(ktr->ktr_error)); 844 } 845 (void)putchar('\n'); 846 } 847 848 void 849 ktrnamei(char *cp, int len) 850 { 851 (void)printf("\"%.*s\"\n", len, cp); 852 } 853 854 void 855 hexdump(char *p, int len, int screenwidth) 856 { 857 int n, i; 858 int width; 859 860 width = 0; 861 do { 862 width += 2; 863 i = 13; /* base offset */ 864 i += (width / 2) + 1; /* spaces every second byte */ 865 i += (width * 2); /* width of bytes */ 866 i += 3; /* " |" */ 867 i += width; /* each byte */ 868 i += 1; /* "|" */ 869 } while (i < screenwidth); 870 width -= 2; 871 872 for (n = 0; n < len; n += width) { 873 for (i = n; i < n + width; i++) { 874 if ((i % width) == 0) { /* beginning of line */ 875 printf(" 0x%04x", i); 876 } 877 if ((i % 2) == 0) { 878 printf(" "); 879 } 880 if (i < len) 881 printf("%02x", p[i] & 0xff); 882 else 883 printf(" "); 884 } 885 printf(" |"); 886 for (i = n; i < n + width; i++) { 887 if (i >= len) 888 break; 889 if (p[i] >= ' ' && p[i] <= '~') 890 printf("%c", p[i]); 891 else 892 printf("."); 893 } 894 printf("|\n"); 895 } 896 if ((i % width) != 0) 897 printf("\n"); 898 } 899 900 void 901 visdump(char *dp, int datalen, int screenwidth) 902 { 903 int col = 0; 904 char *cp; 905 int width; 906 char visbuf[5]; 907 908 (void)printf(" \""); 909 col = 8; 910 for (;datalen > 0; datalen--, dp++) { 911 (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 912 cp = visbuf; 913 /* 914 * Keep track of printables and 915 * space chars (like fold(1)). 916 */ 917 if (col == 0) { 918 (void)putchar('\t'); 919 col = 8; 920 } 921 switch(*cp) { 922 case '\n': 923 col = 0; 924 (void)putchar('\n'); 925 continue; 926 case '\t': 927 width = 8 - (col&07); 928 break; 929 default: 930 width = strlen(cp); 931 } 932 if (col + width > (screenwidth-2)) { 933 (void)printf("\\\n\t"); 934 col = 8; 935 } 936 col += width; 937 do { 938 (void)putchar(*cp++); 939 } while (*cp); 940 } 941 if (col == 0) 942 (void)printf(" "); 943 (void)printf("\"\n"); 944 } 945 946 void 947 ktrgenio(struct ktr_genio *ktr, int len) 948 { 949 int datalen = len - sizeof (struct ktr_genio); 950 char *dp = (char *)ktr + sizeof (struct ktr_genio); 951 static int screenwidth = 0; 952 int i, binary; 953 954 if (screenwidth == 0) { 955 struct winsize ws; 956 957 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 958 ws.ws_col > 8) 959 screenwidth = ws.ws_col; 960 else 961 screenwidth = 80; 962 } 963 printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 964 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 965 datalen == 1 ? "" : "s"); 966 if (suppressdata) 967 return; 968 if (maxdata && datalen > maxdata) 969 datalen = maxdata; 970 971 for (i = 0, binary = 0; i < datalen && binary == 0; i++) { 972 if (dp[i] >= 32 && dp[i] < 127) 973 continue; 974 if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9) 975 continue; 976 binary = 1; 977 } 978 if (binary) 979 hexdump(dp, datalen, screenwidth); 980 else 981 visdump(dp, datalen, screenwidth); 982 } 983 984 const char *signames[] = { 985 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 986 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 987 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 988 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 989 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 990 "USR2", NULL, /* 31 - 32 */ 991 }; 992 993 void 994 ktrpsig(struct ktr_psig *psig) 995 { 996 if (psig->signo > 0 && psig->signo < NSIG) 997 (void)printf("SIG%s ", signames[psig->signo]); 998 else 999 (void)printf("SIG %d ", psig->signo); 1000 if (psig->action == SIG_DFL) 1001 (void)printf("SIG_DFL\n"); 1002 else { 1003 (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 1004 (u_long)psig->action, psig->mask.__bits[0], psig->code); 1005 } 1006 } 1007 1008 void 1009 ktrcsw(struct ktr_csw *cs) 1010 { 1011 (void)printf("%s %s\n", cs->out ? "stop" : "resume", 1012 cs->user ? "user" : "kernel"); 1013 } 1014 1015 #define UTRACE_DLOPEN_START 1 1016 #define UTRACE_DLOPEN_STOP 2 1017 #define UTRACE_DLCLOSE_START 3 1018 #define UTRACE_DLCLOSE_STOP 4 1019 #define UTRACE_LOAD_OBJECT 5 1020 #define UTRACE_UNLOAD_OBJECT 6 1021 #define UTRACE_ADD_RUNDEP 7 1022 #define UTRACE_PRELOAD_FINISHED 8 1023 #define UTRACE_INIT_CALL 9 1024 #define UTRACE_FINI_CALL 10 1025 1026 struct utrace_rtld { 1027 char sig[4]; /* 'RTLD' */ 1028 int event; 1029 void *handle; 1030 void *mapbase; 1031 size_t mapsize; 1032 int refcnt; 1033 char name[MAXPATHLEN]; 1034 }; 1035 1036 void 1037 ktruser_rtld(int len, unsigned char *p) 1038 { 1039 struct utrace_rtld *ut = (struct utrace_rtld *)p; 1040 void *parent; 1041 int mode; 1042 1043 switch (ut->event) { 1044 case UTRACE_DLOPEN_START: 1045 mode = ut->refcnt; 1046 printf("dlopen(%s, ", ut->name); 1047 switch (mode & RTLD_MODEMASK) { 1048 case RTLD_NOW: 1049 printf("RTLD_NOW"); 1050 break; 1051 case RTLD_LAZY: 1052 printf("RTLD_LAZY"); 1053 break; 1054 default: 1055 printf("%#x", mode & RTLD_MODEMASK); 1056 } 1057 if (mode & RTLD_GLOBAL) 1058 printf(" | RTLD_GLOBAL"); 1059 if (mode & RTLD_TRACE) 1060 printf(" | RTLD_TRACE"); 1061 if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)) 1062 printf(" | %#x", mode & 1063 ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)); 1064 printf(")\n"); 1065 break; 1066 case UTRACE_DLOPEN_STOP: 1067 printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name, 1068 ut->refcnt); 1069 break; 1070 case UTRACE_DLCLOSE_START: 1071 printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name, 1072 ut->refcnt); 1073 break; 1074 case UTRACE_DLCLOSE_STOP: 1075 printf("dlclose(%p) finished\n", ut->handle); 1076 break; 1077 case UTRACE_LOAD_OBJECT: 1078 printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle, 1079 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 1080 ut->name); 1081 break; 1082 case UTRACE_UNLOAD_OBJECT: 1083 printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle, 1084 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 1085 ut->name); 1086 break; 1087 case UTRACE_ADD_RUNDEP: 1088 parent = ut->mapbase; 1089 printf("RTLD: %p now depends on %p (%s, %d)\n", parent, 1090 ut->handle, ut->name, ut->refcnt); 1091 break; 1092 case UTRACE_PRELOAD_FINISHED: 1093 printf("RTLD: LD_PRELOAD finished\n"); 1094 break; 1095 case UTRACE_INIT_CALL: 1096 printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle, 1097 ut->name); 1098 break; 1099 case UTRACE_FINI_CALL: 1100 printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle, 1101 ut->name); 1102 break; 1103 default: 1104 p += 4; 1105 len -= 4; 1106 printf("RTLD: %d ", len); 1107 while (len--) 1108 if (decimal) 1109 printf(" %d", *p++); 1110 else 1111 printf(" %02x", *p++); 1112 printf("\n"); 1113 } 1114 } 1115 1116 struct utrace_malloc { 1117 void *p; 1118 size_t s; 1119 void *r; 1120 }; 1121 1122 void 1123 ktruser_malloc(int len, unsigned char *p) 1124 { 1125 struct utrace_malloc *ut = (struct utrace_malloc *)p; 1126 1127 if (ut->p == (void *)(intptr_t)(-1)) 1128 printf("malloc_init()\n"); 1129 else if (ut->s == 0) 1130 printf("free(%p)\n", ut->p); 1131 else if (ut->p == NULL) 1132 printf("%p = malloc(%zu)\n", ut->r, ut->s); 1133 else 1134 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); 1135 } 1136 1137 void 1138 ktruser(int len, unsigned char *p) 1139 { 1140 1141 if (len >= 8 && bcmp(p, "RTLD", 4) == 0) { 1142 ktruser_rtld(len, p); 1143 return; 1144 } 1145 1146 if (len == sizeof(struct utrace_malloc)) { 1147 ktruser_malloc(len, p); 1148 return; 1149 } 1150 1151 (void)printf("%d ", len); 1152 while (len--) 1153 if (decimal) 1154 (void)printf(" %d", *p++); 1155 else 1156 (void)printf(" %02x", *p++); 1157 (void)printf("\n"); 1158 } 1159 1160 void 1161 ktrsockaddr(struct sockaddr *sa) 1162 { 1163 /* 1164 TODO: Support additional address families 1165 #include <netnatm/natm.h> 1166 struct sockaddr_natm *natm; 1167 #include <netsmb/netbios.h> 1168 struct sockaddr_nb *nb; 1169 */ 1170 char addr[64]; 1171 1172 /* 1173 * note: ktrstruct() has already verified that sa points to a 1174 * buffer at least sizeof(struct sockaddr) bytes long and exactly 1175 * sa->sa_len bytes long. 1176 */ 1177 printf("struct sockaddr { "); 1178 sockfamilyname(sa->sa_family); 1179 printf(", "); 1180 1181 #define check_sockaddr_len(n) \ 1182 if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \ 1183 printf("invalid"); \ 1184 break; \ 1185 } 1186 1187 switch(sa->sa_family) { 1188 case AF_INET: { 1189 struct sockaddr_in *sa_in; 1190 1191 sa_in = (struct sockaddr_in *)sa; 1192 check_sockaddr_len(in); 1193 inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr); 1194 printf("%s:%u", addr, ntohs(sa_in->sin_port)); 1195 break; 1196 } 1197 #ifdef NETATALK 1198 case AF_APPLETALK: { 1199 struct sockaddr_at *sa_at; 1200 struct netrange *nr; 1201 1202 sa_at = (struct sockaddr_at *)sa; 1203 check_sockaddr_len(at); 1204 nr = &sa_at->sat_range.r_netrange; 1205 printf("%d.%d, %d-%d, %d", ntohs(sa_at->sat_addr.s_net), 1206 sa_at->sat_addr.s_node, ntohs(nr->nr_firstnet), 1207 ntohs(nr->nr_lastnet), nr->nr_phase); 1208 break; 1209 } 1210 #endif 1211 case AF_INET6: { 1212 struct sockaddr_in6 *sa_in6; 1213 1214 sa_in6 = (struct sockaddr_in6 *)sa; 1215 check_sockaddr_len(in6); 1216 inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr); 1217 printf("[%s]:%u", addr, htons(sa_in6->sin6_port)); 1218 break; 1219 } 1220 #ifdef IPX 1221 case AF_IPX: { 1222 struct sockaddr_ipx *sa_ipx; 1223 1224 sa_ipx = (struct sockaddr_ipx *)sa; 1225 check_sockaddr_len(ipx); 1226 /* XXX wish we had ipx_ntop */ 1227 printf("%s", ipx_ntoa(sa_ipx->sipx_addr)); 1228 break; 1229 } 1230 #endif 1231 case AF_UNIX: { 1232 struct sockaddr_un *sa_un; 1233 1234 sa_un = (struct sockaddr_un *)sa; 1235 check_sockaddr_len(un); 1236 printf("%.*s", (int)sizeof(sa_un->sun_path), sa_un->sun_path); 1237 break; 1238 } 1239 default: 1240 printf("unknown address family"); 1241 } 1242 printf(" }\n"); 1243 } 1244 1245 void 1246 ktrstat(struct stat *statp) 1247 { 1248 char mode[12], timestr[PATH_MAX + 4]; 1249 struct passwd *pwd; 1250 struct group *grp; 1251 struct tm *tm; 1252 1253 /* 1254 * note: ktrstruct() has already verified that statp points to a 1255 * buffer exactly sizeof(struct stat) bytes long. 1256 */ 1257 printf("struct stat {"); 1258 strmode(statp->st_mode, mode); 1259 printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ", 1260 (uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode, 1261 (uintmax_t)statp->st_nlink); 1262 if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL) 1263 printf("uid=%ju, ", (uintmax_t)statp->st_uid); 1264 else 1265 printf("uid=\"%s\", ", pwd->pw_name); 1266 if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL) 1267 printf("gid=%ju, ", (uintmax_t)statp->st_gid); 1268 else 1269 printf("gid=\"%s\", ", grp->gr_name); 1270 printf("rdev=%ju, ", (uintmax_t)statp->st_rdev); 1271 printf("atime="); 1272 if (resolv == 0) 1273 printf("%jd", (intmax_t)statp->st_atimespec.tv_sec); 1274 else { 1275 tm = localtime(&statp->st_atimespec.tv_sec); 1276 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1277 printf("\"%s\"", timestr); 1278 } 1279 if (statp->st_atimespec.tv_nsec != 0) 1280 printf(".%09ld, ", statp->st_atimespec.tv_nsec); 1281 else 1282 printf(", "); 1283 printf("stime="); 1284 if (resolv == 0) 1285 printf("%jd", (intmax_t)statp->st_mtimespec.tv_sec); 1286 else { 1287 tm = localtime(&statp->st_mtimespec.tv_sec); 1288 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1289 printf("\"%s\"", timestr); 1290 } 1291 if (statp->st_mtimespec.tv_nsec != 0) 1292 printf(".%09ld, ", statp->st_mtimespec.tv_nsec); 1293 else 1294 printf(", "); 1295 printf("ctime="); 1296 if (resolv == 0) 1297 printf("%jd", (intmax_t)statp->st_ctimespec.tv_sec); 1298 else { 1299 tm = localtime(&statp->st_ctimespec.tv_sec); 1300 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1301 printf("\"%s\"", timestr); 1302 } 1303 if (statp->st_ctimespec.tv_nsec != 0) 1304 printf(".%09ld, ", statp->st_ctimespec.tv_nsec); 1305 else 1306 printf(", "); 1307 printf("birthtime="); 1308 if (resolv == 0) 1309 printf("%jd", (intmax_t)statp->st_birthtimespec.tv_sec); 1310 else { 1311 tm = localtime(&statp->st_birthtimespec.tv_sec); 1312 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1313 printf("\"%s\"", timestr); 1314 } 1315 if (statp->st_birthtimespec.tv_nsec != 0) 1316 printf(".%09ld, ", statp->st_birthtimespec.tv_nsec); 1317 else 1318 printf(", "); 1319 printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x", 1320 (uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize, 1321 (intmax_t)statp->st_blocks, statp->st_flags); 1322 printf(" }\n"); 1323 } 1324 1325 void 1326 ktrstruct(char *buf, size_t buflen) 1327 { 1328 char *name, *data; 1329 size_t namelen, datalen; 1330 int i; 1331 struct stat sb; 1332 struct sockaddr_storage ss; 1333 1334 for (name = buf, namelen = 0; 1335 namelen < buflen && name[namelen] != '\0'; 1336 ++namelen) 1337 /* nothing */; 1338 if (namelen == buflen) 1339 goto invalid; 1340 if (name[namelen] != '\0') 1341 goto invalid; 1342 data = buf + namelen + 1; 1343 datalen = buflen - namelen - 1; 1344 if (datalen == 0) 1345 goto invalid; 1346 /* sanity check */ 1347 for (i = 0; i < namelen; ++i) 1348 if (!isalpha((unsigned char)name[i])) 1349 goto invalid; 1350 if (strcmp(name, "stat") == 0) { 1351 if (datalen != sizeof(struct stat)) 1352 goto invalid; 1353 memcpy(&sb, data, datalen); 1354 ktrstat(&sb); 1355 } else if (strcmp(name, "sockaddr") == 0) { 1356 if (datalen > sizeof(ss)) 1357 goto invalid; 1358 memcpy(&ss, data, datalen); 1359 if (datalen < sizeof(struct sockaddr) || 1360 datalen != ss.ss_len) 1361 goto invalid; 1362 ktrsockaddr((struct sockaddr *)&ss); 1363 } else { 1364 printf("unknown structure\n"); 1365 } 1366 return; 1367 invalid: 1368 printf("invalid record\n"); 1369 } 1370 1371 void 1372 usage(void) 1373 { 1374 fprintf(stderr, "usage: kdump [-dEnlHRrsT] [-f trfile] " 1375 "[-m maxdata] [-p pid] [-t trstr]\n"); 1376 exit(1); 1377 } 1378