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 <dlfcn.h> 62 #include <err.h> 63 #include <locale.h> 64 #include <stdio.h> 65 #include <stdlib.h> 66 #include <string.h> 67 #include <unistd.h> 68 #include <vis.h> 69 #include "ktrace.h" 70 #include "kdump_subr.h" 71 72 int fread_tail(void *, int, int); 73 void dumpheader(struct ktr_header *); 74 void ktrsyscall(struct ktr_syscall *); 75 void ktrsysret(struct ktr_sysret *); 76 void ktrnamei(char *, int); 77 void hexdump(char *, int, int); 78 void visdump(char *, int, int); 79 void ktrgenio(struct ktr_genio *, int); 80 void ktrpsig(struct ktr_psig *); 81 void ktrcsw(struct ktr_csw *); 82 void ktruser(int, unsigned char *); 83 void usage(void); 84 const char *ioctlname(u_long); 85 86 int timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata; 87 const char *tracefile = DEF_TRACEFILE; 88 struct ktr_header ktr_header; 89 90 #define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 91 92 int 93 main(int argc, char *argv[]) 94 { 95 int ch, ktrlen, size; 96 void *m; 97 int trpoints = ALL_POINTS; 98 int drop_logged; 99 pid_t pid = 0; 100 101 (void) setlocale(LC_CTYPE, ""); 102 103 while ((ch = getopt(argc,argv,"f:dElm:np:HRsTt:")) != -1) 104 switch((char)ch) { 105 case 'f': 106 tracefile = optarg; 107 break; 108 case 'd': 109 decimal = 1; 110 break; 111 case 'l': 112 tail = 1; 113 break; 114 case 'm': 115 maxdata = atoi(optarg); 116 break; 117 case 'n': 118 fancy = 0; 119 break; 120 case 'p': 121 pid = atoi(optarg); 122 break; 123 case 's': 124 suppressdata = 1; 125 break; 126 case 'E': 127 timestamp = 3; /* elapsed timestamp */ 128 break; 129 case 'H': 130 threads = 1; 131 break; 132 case 'R': 133 timestamp = 2; /* relative timestamp */ 134 break; 135 case 'T': 136 timestamp = 1; 137 break; 138 case 't': 139 trpoints = getpoints(optarg); 140 if (trpoints < 0) 141 errx(1, "unknown trace point in %s", optarg); 142 break; 143 default: 144 usage(); 145 } 146 147 if (argc > optind) 148 usage(); 149 150 m = (void *)malloc(size = 1025); 151 if (m == NULL) 152 errx(1, "%s", strerror(ENOMEM)); 153 if (!freopen(tracefile, "r", stdin)) 154 err(1, "%s", tracefile); 155 drop_logged = 0; 156 while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 157 if (ktr_header.ktr_type & KTR_DROP) { 158 ktr_header.ktr_type &= ~KTR_DROP; 159 if (!drop_logged && threads) { 160 (void)printf("%6d %6d %-8.*s Events dropped.\n", 161 ktr_header.ktr_pid, ktr_header.ktr_tid > 162 0 ? ktr_header.ktr_tid : 0, MAXCOMLEN, 163 ktr_header.ktr_comm); 164 drop_logged = 1; 165 } else if (!drop_logged) { 166 (void)printf("%6d %-8.*s Events dropped.\n", 167 ktr_header.ktr_pid, MAXCOMLEN, 168 ktr_header.ktr_comm); 169 drop_logged = 1; 170 } 171 } 172 if (trpoints & (1<<ktr_header.ktr_type)) 173 if (pid == 0 || ktr_header.ktr_pid == pid) 174 dumpheader(&ktr_header); 175 if ((ktrlen = ktr_header.ktr_len) < 0) 176 errx(1, "bogus length 0x%x", ktrlen); 177 if (ktrlen > size) { 178 m = (void *)realloc(m, ktrlen+1); 179 if (m == NULL) 180 errx(1, "%s", strerror(ENOMEM)); 181 size = ktrlen; 182 } 183 if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 184 errx(1, "data too short"); 185 if (pid && ktr_header.ktr_pid != pid) 186 continue; 187 if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 188 continue; 189 drop_logged = 0; 190 switch (ktr_header.ktr_type) { 191 case KTR_SYSCALL: 192 ktrsyscall((struct ktr_syscall *)m); 193 break; 194 case KTR_SYSRET: 195 ktrsysret((struct ktr_sysret *)m); 196 break; 197 case KTR_NAMEI: 198 ktrnamei(m, ktrlen); 199 break; 200 case KTR_GENIO: 201 ktrgenio((struct ktr_genio *)m, ktrlen); 202 break; 203 case KTR_PSIG: 204 ktrpsig((struct ktr_psig *)m); 205 break; 206 case KTR_CSW: 207 ktrcsw((struct ktr_csw *)m); 208 break; 209 case KTR_USER: 210 ktruser(ktrlen, m); 211 break; 212 default: 213 printf("\n"); 214 break; 215 } 216 if (tail) 217 (void)fflush(stdout); 218 } 219 return 0; 220 } 221 222 int 223 fread_tail(void *buf, int size, int num) 224 { 225 int i; 226 227 while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 228 (void)sleep(1); 229 clearerr(stdin); 230 } 231 return (i); 232 } 233 234 void 235 dumpheader(struct ktr_header *kth) 236 { 237 static char unknown[64]; 238 static struct timeval prevtime, temp; 239 const char *type; 240 241 switch (kth->ktr_type) { 242 case KTR_SYSCALL: 243 type = "CALL"; 244 break; 245 case KTR_SYSRET: 246 type = "RET "; 247 break; 248 case KTR_NAMEI: 249 type = "NAMI"; 250 break; 251 case KTR_GENIO: 252 type = "GIO "; 253 break; 254 case KTR_PSIG: 255 type = "PSIG"; 256 break; 257 case KTR_CSW: 258 type = "CSW "; 259 break; 260 case KTR_USER: 261 type = "USER"; 262 break; 263 default: 264 (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 265 type = unknown; 266 } 267 268 /* 269 * The ktr_tid field was previously the ktr_buffer field, which held 270 * the kernel pointer value for the buffer associated with data 271 * following the record header. It now holds a threadid, but only 272 * for trace files after the change. Older trace files still contain 273 * kernel pointers. Detect this and suppress the results by printing 274 * negative tid's as 0. 275 */ 276 if (threads) 277 (void)printf("%6d %6d %-8.*s ", kth->ktr_pid, kth->ktr_tid > 278 0 ? kth->ktr_tid : 0, MAXCOMLEN, kth->ktr_comm); 279 else 280 (void)printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN, 281 kth->ktr_comm); 282 if (timestamp) { 283 if (timestamp == 3) { 284 if (prevtime.tv_sec == 0) 285 prevtime = kth->ktr_time; 286 timevalsub(&kth->ktr_time, &prevtime); 287 } 288 if (timestamp == 2) { 289 temp = kth->ktr_time; 290 timevalsub(&kth->ktr_time, &prevtime); 291 prevtime = temp; 292 } 293 (void)printf("%ld.%06ld ", 294 kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); 295 } 296 (void)printf("%s ", type); 297 } 298 299 #include <sys/syscall.h> 300 #define KTRACE 301 #include <sys/kern/syscalls.c> 302 #undef KTRACE 303 int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 304 305 void 306 ktrsyscall(struct ktr_syscall *ktr) 307 { 308 int narg = ktr->ktr_narg; 309 register_t *ip; 310 311 if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) 312 (void)printf("[%d]", ktr->ktr_code); 313 else 314 (void)printf("%s", syscallnames[ktr->ktr_code]); 315 ip = &ktr->ktr_args[0]; 316 if (narg) { 317 char c = '('; 318 if (fancy) { 319 320 #define print_number(i,n,c) do { \ 321 if (decimal) \ 322 (void)printf("%c%ld", c, (long)*i); \ 323 else \ 324 (void)printf("%c%#lx", c, (long)*i); \ 325 i++; \ 326 n--; \ 327 c = ','; \ 328 } while (0); 329 330 if (ktr->ktr_code == SYS_ioctl) { 331 const char *cp; 332 print_number(ip,narg,c); 333 if ((cp = ioctlname(*ip)) != NULL) 334 (void)printf(",%s", cp); 335 else { 336 if (decimal) 337 (void)printf(",%ld", (long)*ip); 338 else 339 (void)printf(",%#lx ", (long)*ip); 340 } 341 c = ','; 342 ip++; 343 narg--; 344 } else if (ktr->ktr_code == SYS_ptrace) { 345 (void)putchar('('); 346 ptraceopname ((int)*ip); 347 c = ','; 348 ip++; 349 narg--; 350 } else if (ktr->ktr_code == SYS_access || 351 ktr->ktr_code == SYS_eaccess) { 352 print_number(ip,narg,c); 353 (void)putchar(','); 354 accessmodename ((int)*ip); 355 ip++; 356 narg--; 357 } else if (ktr->ktr_code == SYS_open) { 358 int flags; 359 int mode; 360 print_number(ip,narg,c); 361 flags = *ip; 362 mode = *++ip; 363 (void)putchar(','); 364 flagsandmodename (flags, mode, decimal); 365 ip++; 366 narg-=2; 367 } else if (ktr->ktr_code == SYS_wait4) { 368 print_number(ip,narg,c); 369 print_number(ip,narg,c); 370 (void)putchar(','); 371 wait4optname ((int)*ip); 372 ip++; 373 narg--; 374 } else if (ktr->ktr_code == SYS_chmod || 375 ktr->ktr_code == SYS_fchmod || 376 ktr->ktr_code == SYS_lchmod) { 377 print_number(ip,narg,c); 378 (void)putchar(','); 379 modename ((int)*ip); 380 ip++; 381 narg--; 382 } else if (ktr->ktr_code == SYS_mknod) { 383 print_number(ip,narg,c); 384 (void)putchar(','); 385 modename ((int)*ip); 386 ip++; 387 narg--; 388 } else if (ktr->ktr_code == SYS_getfsstat) { 389 print_number(ip,narg,c); 390 print_number(ip,narg,c); 391 (void)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 (void)putchar(','); 399 mountflagsname ((int)*ip); 400 ip++; 401 narg--; 402 } else if (ktr->ktr_code == SYS_unmount) { 403 print_number(ip,narg,c); 404 (void)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 (void)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 (void)putchar(','); 422 sendrecvflagsname ((int)*ip); 423 ip++; 424 narg--; 425 } else if (ktr->ktr_code == SYS_chflags || 426 ktr->ktr_code == SYS_fchflags || 427 ktr->ktr_code == SYS_lchflags) { 428 print_number(ip,narg,c); 429 (void)putchar(','); 430 modename((int)*ip); 431 ip++; 432 narg--; 433 } else if (ktr->ktr_code == SYS_kill) { 434 print_number(ip,narg,c); 435 (void)putchar(','); 436 signame((int)*ip); 437 ip++; 438 narg--; 439 } else if (ktr->ktr_code == SYS_reboot) { 440 (void)putchar('('); 441 rebootoptname((int)*ip); 442 ip++; 443 narg--; 444 } else if (ktr->ktr_code == SYS_umask) { 445 (void)putchar('('); 446 modename((int)*ip); 447 ip++; 448 narg--; 449 } else if (ktr->ktr_code == SYS_msync) { 450 print_number(ip,narg,c); 451 print_number(ip,narg,c); 452 (void)putchar(','); 453 msyncflagsname((int)*ip); 454 ip++; 455 narg--; 456 #ifdef SYS_freebsd6_mmap 457 } else if (ktr->ktr_code == SYS_freebsd6_mmap) { 458 print_number(ip,narg,c); 459 print_number(ip,narg,c); 460 (void)putchar(','); 461 mmapprotname ((int)*ip); 462 (void)putchar(','); 463 ip++; 464 narg--; 465 mmapflagsname ((int)*ip); 466 ip++; 467 narg--; 468 #endif 469 } else if (ktr->ktr_code == SYS_mmap) { 470 print_number(ip,narg,c); 471 print_number(ip,narg,c); 472 (void)putchar(','); 473 mmapprotname ((int)*ip); 474 (void)putchar(','); 475 ip++; 476 narg--; 477 mmapflagsname ((int)*ip); 478 ip++; 479 narg--; 480 } else if (ktr->ktr_code == SYS_mprotect) { 481 print_number(ip,narg,c); 482 print_number(ip,narg,c); 483 (void)putchar(','); 484 mmapprotname ((int)*ip); 485 ip++; 486 narg--; 487 } else if (ktr->ktr_code == SYS_madvise) { 488 print_number(ip,narg,c); 489 print_number(ip,narg,c); 490 (void)putchar(','); 491 madvisebehavname((int)*ip); 492 ip++; 493 narg--; 494 } else if (ktr->ktr_code == SYS_setpriority) { 495 print_number(ip,narg,c); 496 print_number(ip,narg,c); 497 (void)putchar(','); 498 prioname((int)*ip); 499 ip++; 500 narg--; 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 (void)putchar(','); 508 fcntlcmdname(cmd, arg, decimal); 509 ip++; 510 narg-=2; 511 } else if (ktr->ktr_code == SYS_socket) { 512 int sockdomain; 513 (void)putchar('('); 514 sockdomain=(int)*ip; 515 sockdomainname(sockdomain); 516 ip++; 517 narg--; 518 (void)putchar(','); 519 socktypename((int)*ip); 520 ip++; 521 narg--; 522 if (sockdomain == PF_INET || 523 sockdomain == PF_INET6) { 524 (void)putchar(','); 525 sockipprotoname((int)*ip); 526 ip++; 527 narg--; 528 } 529 c = ','; 530 } else if (ktr->ktr_code == SYS_setsockopt || 531 ktr->ktr_code == SYS_getsockopt) { 532 print_number(ip,narg,c); 533 (void)putchar(','); 534 sockoptlevelname((int)*ip, decimal); 535 ip++; 536 narg--; 537 (void)putchar(','); 538 sockoptname((int)*ip); 539 ip++; 540 narg--; 541 #ifdef SYS_freebsd6_lseek 542 } else if (ktr->ktr_code == SYS_freebsd6_lseek) { 543 print_number(ip,narg,c); 544 /* Hidden 'pad' argument, not in lseek(2) */ 545 print_number(ip,narg,c); 546 print_number(ip,narg,c); 547 (void)putchar(','); 548 whencename ((int)*ip); 549 ip++; 550 narg--; 551 #endif 552 } else if (ktr->ktr_code == SYS_lseek) { 553 print_number(ip,narg,c); 554 /* Hidden 'pad' argument, not in lseek(2) */ 555 print_number(ip,narg,c); 556 (void)putchar(','); 557 whencename ((int)*ip); 558 ip++; 559 narg--; 560 561 } else if (ktr->ktr_code == SYS_flock) { 562 print_number(ip,narg,c); 563 (void)putchar(','); 564 flockname((int)*ip); 565 ip++; 566 narg--; 567 } else if (ktr->ktr_code == SYS_mkfifo || 568 ktr->ktr_code == SYS_mkdir) { 569 print_number(ip,narg,c); 570 (void)putchar(','); 571 modename((int)*ip); 572 ip++; 573 narg--; 574 } else if (ktr->ktr_code == SYS_shutdown) { 575 print_number(ip,narg,c); 576 (void)putchar(','); 577 shutdownhowname((int)*ip); 578 ip++; 579 narg--; 580 } else if (ktr->ktr_code == SYS_socketpair) { 581 (void)putchar('('); 582 sockdomainname((int)*ip); 583 ip++; 584 narg--; 585 (void)putchar(','); 586 socktypename((int)*ip); 587 ip++; 588 narg--; 589 c = ','; 590 } else if (ktr->ktr_code == SYS_getrlimit || 591 ktr->ktr_code == SYS_setrlimit) { 592 (void)putchar('('); 593 rlimitname((int)*ip); 594 ip++; 595 narg--; 596 c = ','; 597 } else if (ktr->ktr_code == SYS_quotactl) { 598 print_number(ip,narg,c); 599 (void)putchar(','); 600 quotactlname((int)*ip); 601 ip++; 602 narg--; 603 c = ','; 604 } else if (ktr->ktr_code == SYS_nfssvc) { 605 (void)putchar('('); 606 nfssvcname((int)*ip); 607 ip++; 608 narg--; 609 c = ','; 610 } else if (ktr->ktr_code == SYS_rtprio) { 611 (void)putchar('('); 612 rtprioname((int)*ip); 613 ip++; 614 narg--; 615 c = ','; 616 } else if (ktr->ktr_code == SYS___semctl) { 617 print_number(ip,narg,c); 618 print_number(ip,narg,c); 619 (void)putchar(','); 620 semctlname((int)*ip); 621 ip++; 622 narg--; 623 } else if (ktr->ktr_code == SYS_semget) { 624 print_number(ip,narg,c); 625 print_number(ip,narg,c); 626 (void)putchar(','); 627 semgetname((int)*ip); 628 ip++; 629 narg--; 630 } else if (ktr->ktr_code == SYS_msgctl) { 631 print_number(ip,narg,c); 632 (void)putchar(','); 633 shmctlname((int)*ip); 634 ip++; 635 narg--; 636 } else if (ktr->ktr_code == SYS_shmat) { 637 print_number(ip,narg,c); 638 print_number(ip,narg,c); 639 (void)putchar(','); 640 shmatname((int)*ip); 641 ip++; 642 narg--; 643 } else if (ktr->ktr_code == SYS_shmctl) { 644 print_number(ip,narg,c); 645 (void)putchar(','); 646 shmctlname((int)*ip); 647 ip++; 648 narg--; 649 } else if (ktr->ktr_code == SYS_minherit) { 650 print_number(ip,narg,c); 651 print_number(ip,narg,c); 652 (void)putchar(','); 653 minheritname((int)*ip); 654 ip++; 655 narg--; 656 } else if (ktr->ktr_code == SYS_rfork) { 657 (void)putchar('('); 658 rforkname((int)*ip); 659 ip++; 660 narg--; 661 c = ','; 662 } else if (ktr->ktr_code == SYS_lio_listio) { 663 (void)putchar('('); 664 lio_listioname((int)*ip); 665 ip++; 666 narg--; 667 c = ','; 668 } else if (ktr->ktr_code == SYS_mlockall) { 669 (void)putchar('('); 670 mlockallname((int)*ip); 671 ip++; 672 narg--; 673 } else if (ktr->ktr_code == SYS_sched_setscheduler) { 674 print_number(ip,narg,c); 675 (void)putchar(','); 676 schedpolicyname((int)*ip); 677 ip++; 678 narg--; 679 } else if (ktr->ktr_code == SYS_sched_get_priority_max || 680 ktr->ktr_code == SYS_sched_get_priority_min) { 681 (void)putchar('('); 682 schedpolicyname((int)*ip); 683 ip++; 684 narg--; 685 } else if (ktr->ktr_code == SYS_sendfile) { 686 print_number(ip,narg,c); 687 print_number(ip,narg,c); 688 print_number(ip,narg,c); 689 print_number(ip,narg,c); 690 print_number(ip,narg,c); 691 print_number(ip,narg,c); 692 (void)putchar(','); 693 sendfileflagsname((int)*ip); 694 ip++; 695 narg--; 696 } else if (ktr->ktr_code == SYS_kldsym) { 697 print_number(ip,narg,c); 698 (void)putchar(','); 699 kldsymcmdname((int)*ip); 700 ip++; 701 narg--; 702 } else if (ktr->ktr_code == SYS_sigprocmask) { 703 (void)putchar('('); 704 sigprocmaskhowname((int)*ip); 705 ip++; 706 narg--; 707 c = ','; 708 } else if (ktr->ktr_code == SYS___acl_get_file || 709 ktr->ktr_code == SYS___acl_set_file || 710 ktr->ktr_code == SYS___acl_get_fd || 711 ktr->ktr_code == SYS___acl_set_fd || 712 ktr->ktr_code == SYS___acl_delete_file || 713 ktr->ktr_code == SYS___acl_delete_fd || 714 ktr->ktr_code == SYS___acl_aclcheck_file || 715 ktr->ktr_code == SYS___acl_aclcheck_fd || 716 ktr->ktr_code == SYS___acl_get_link || 717 ktr->ktr_code == SYS___acl_set_link || 718 ktr->ktr_code == SYS___acl_delete_link || 719 ktr->ktr_code == SYS___acl_aclcheck_link) { 720 print_number(ip,narg,c); 721 (void)putchar(','); 722 acltypename((int)*ip); 723 ip++; 724 narg--; 725 } else if (ktr->ktr_code == SYS_sigaction) { 726 (void)putchar('('); 727 signame((int)*ip); 728 ip++; 729 narg--; 730 c = ','; 731 } else if (ktr->ktr_code == SYS_extattrctl) { 732 print_number(ip,narg,c); 733 (void)putchar(','); 734 extattrctlname((int)*ip); 735 ip++; 736 narg--; 737 } else if (ktr->ktr_code == SYS_nmount) { 738 print_number(ip,narg,c); 739 print_number(ip,narg,c); 740 (void)putchar(','); 741 mountflagsname ((int)*ip); 742 ip++; 743 narg--; 744 } else if (ktr->ktr_code == SYS_kse_thr_interrupt) { 745 print_number(ip,narg,c); 746 (void)putchar(','); 747 ksethrcmdname ((int)*ip); 748 ip++; 749 narg--; 750 } else if (ktr->ktr_code == SYS_thr_create) { 751 print_number(ip,narg,c); 752 print_number(ip,narg,c); 753 (void)putchar(','); 754 thrcreateflagsname ((int)*ip); 755 ip++; 756 narg--; 757 } else if (ktr->ktr_code == SYS_thr_kill) { 758 print_number(ip,narg,c); 759 (void)putchar(','); 760 signame ((int)*ip); 761 ip++; 762 narg--; 763 } else if (ktr->ktr_code == SYS_kldunloadf) { 764 print_number(ip,narg,c); 765 (void)putchar(','); 766 kldunloadfflagsname ((int)*ip); 767 ip++; 768 narg--; 769 } 770 } 771 while (narg) { 772 print_number(ip,narg,c); 773 } 774 (void)putchar(')'); 775 } 776 (void)putchar('\n'); 777 } 778 779 void 780 ktrsysret(struct ktr_sysret *ktr) 781 { 782 register_t ret = ktr->ktr_retval; 783 int error = ktr->ktr_error; 784 int code = ktr->ktr_code; 785 786 if (code >= nsyscalls || code < 0) 787 (void)printf("[%d] ", code); 788 else 789 (void)printf("%s ", syscallnames[code]); 790 791 if (error == 0) { 792 if (fancy) { 793 (void)printf("%d", ret); 794 if (ret < 0 || ret > 9) 795 (void)printf("/%#lx", (long)ret); 796 } else { 797 if (decimal) 798 (void)printf("%ld", (long)ret); 799 else 800 (void)printf("%#lx", (long)ret); 801 } 802 } else if (error == ERESTART) 803 (void)printf("RESTART"); 804 else if (error == EJUSTRETURN) 805 (void)printf("JUSTRETURN"); 806 else { 807 (void)printf("-1 errno %d", ktr->ktr_error); 808 if (fancy) 809 (void)printf(" %s", strerror(ktr->ktr_error)); 810 } 811 (void)putchar('\n'); 812 } 813 814 void 815 ktrnamei(char *cp, int len) 816 { 817 (void)printf("\"%.*s\"\n", len, cp); 818 } 819 820 void 821 hexdump(char *p, int len, int screenwidth) 822 { 823 int n, i; 824 int width; 825 826 width = 0; 827 do { 828 width += 2; 829 i = 13; /* base offset */ 830 i += (width / 2) + 1; /* spaces every second byte */ 831 i += (width * 2); /* width of bytes */ 832 i += 3; /* " |" */ 833 i += width; /* each byte */ 834 i += 1; /* "|" */ 835 } while (i < screenwidth); 836 width -= 2; 837 838 for (n = 0; n < len; n += width) { 839 for (i = n; i < n + width; i++) { 840 if ((i % width) == 0) { /* beginning of line */ 841 printf(" 0x%04x", i); 842 } 843 if ((i % 2) == 0) { 844 printf(" "); 845 } 846 if (i < len) 847 printf("%02x", p[i] & 0xff); 848 else 849 printf(" "); 850 } 851 printf(" |"); 852 for (i = n; i < n + width; i++) { 853 if (i >= len) 854 break; 855 if (p[i] >= ' ' && p[i] <= '~') 856 printf("%c", p[i]); 857 else 858 printf("."); 859 } 860 printf("|\n"); 861 } 862 if ((i % width) != 0) 863 printf("\n"); 864 } 865 866 void 867 visdump(char *dp, int datalen, int screenwidth) 868 { 869 int col = 0; 870 char *cp; 871 int width; 872 char visbuf[5]; 873 874 (void)printf(" \""); 875 col = 8; 876 for (;datalen > 0; datalen--, dp++) { 877 (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 878 cp = visbuf; 879 /* 880 * Keep track of printables and 881 * space chars (like fold(1)). 882 */ 883 if (col == 0) { 884 (void)putchar('\t'); 885 col = 8; 886 } 887 switch(*cp) { 888 case '\n': 889 col = 0; 890 (void)putchar('\n'); 891 continue; 892 case '\t': 893 width = 8 - (col&07); 894 break; 895 default: 896 width = strlen(cp); 897 } 898 if (col + width > (screenwidth-2)) { 899 (void)printf("\\\n\t"); 900 col = 8; 901 } 902 col += width; 903 do { 904 (void)putchar(*cp++); 905 } while (*cp); 906 } 907 if (col == 0) 908 (void)printf(" "); 909 (void)printf("\"\n"); 910 } 911 912 void 913 ktrgenio(struct ktr_genio *ktr, int len) 914 { 915 int datalen = len - sizeof (struct ktr_genio); 916 char *dp = (char *)ktr + sizeof (struct ktr_genio); 917 static int screenwidth = 0; 918 int i, binary; 919 920 if (screenwidth == 0) { 921 struct winsize ws; 922 923 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 924 ws.ws_col > 8) 925 screenwidth = ws.ws_col; 926 else 927 screenwidth = 80; 928 } 929 printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 930 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 931 datalen == 1 ? "" : "s"); 932 if (suppressdata) 933 return; 934 if (maxdata && datalen > maxdata) 935 datalen = maxdata; 936 937 for (i = 0, binary = 0; i < datalen && binary == 0; i++) { 938 if (dp[i] >= 32 && dp[i] < 127) 939 continue; 940 if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9) 941 continue; 942 binary = 1; 943 } 944 if (binary) 945 hexdump(dp, datalen, screenwidth); 946 else 947 visdump(dp, datalen, screenwidth); 948 } 949 950 const char *signames[] = { 951 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 952 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 953 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 954 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 955 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 956 "USR2", NULL, /* 31 - 32 */ 957 }; 958 959 void 960 ktrpsig(struct ktr_psig *psig) 961 { 962 if (psig->signo > 0 && psig->signo < NSIG) 963 (void)printf("SIG%s ", signames[psig->signo]); 964 else 965 (void)printf("SIG %d ", psig->signo); 966 if (psig->action == SIG_DFL) 967 (void)printf("SIG_DFL\n"); 968 else { 969 (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 970 (u_long)psig->action, psig->mask.__bits[0], psig->code); 971 } 972 } 973 974 void 975 ktrcsw(struct ktr_csw *cs) 976 { 977 (void)printf("%s %s\n", cs->out ? "stop" : "resume", 978 cs->user ? "user" : "kernel"); 979 } 980 981 #define UTRACE_DLOPEN_START 1 982 #define UTRACE_DLOPEN_STOP 2 983 #define UTRACE_DLCLOSE_START 3 984 #define UTRACE_DLCLOSE_STOP 4 985 #define UTRACE_LOAD_OBJECT 5 986 #define UTRACE_UNLOAD_OBJECT 6 987 #define UTRACE_ADD_RUNDEP 7 988 #define UTRACE_PRELOAD_FINISHED 8 989 #define UTRACE_INIT_CALL 9 990 #define UTRACE_FINI_CALL 10 991 992 struct utrace_rtld { 993 char sig[4]; /* 'RTLD' */ 994 int event; 995 void *handle; 996 void *mapbase; 997 size_t mapsize; 998 int refcnt; 999 char name[MAXPATHLEN]; 1000 }; 1001 1002 void 1003 ktruser_rtld(int len, unsigned char *p) 1004 { 1005 struct utrace_rtld *ut = (struct utrace_rtld *)p; 1006 void *parent; 1007 int mode; 1008 1009 switch (ut->event) { 1010 case UTRACE_DLOPEN_START: 1011 mode = ut->refcnt; 1012 printf("dlopen(%s, ", ut->name); 1013 switch (mode & RTLD_MODEMASK) { 1014 case RTLD_NOW: 1015 printf("RTLD_NOW"); 1016 break; 1017 case RTLD_LAZY: 1018 printf("RTLD_LAZY"); 1019 break; 1020 default: 1021 printf("%#x", mode & RTLD_MODEMASK); 1022 } 1023 if (mode & RTLD_GLOBAL) 1024 printf(" | RTLD_GLOBAL"); 1025 if (mode & RTLD_TRACE) 1026 printf(" | RTLD_TRACE"); 1027 if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)) 1028 printf(" | %#x", mode & 1029 ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)); 1030 printf(")\n"); 1031 break; 1032 case UTRACE_DLOPEN_STOP: 1033 printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name, 1034 ut->refcnt); 1035 break; 1036 case UTRACE_DLCLOSE_START: 1037 printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name, 1038 ut->refcnt); 1039 break; 1040 case UTRACE_DLCLOSE_STOP: 1041 printf("dlclose(%p) finished\n", ut->handle); 1042 break; 1043 case UTRACE_LOAD_OBJECT: 1044 printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle, 1045 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 1046 ut->name); 1047 break; 1048 case UTRACE_UNLOAD_OBJECT: 1049 printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle, 1050 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 1051 ut->name); 1052 break; 1053 case UTRACE_ADD_RUNDEP: 1054 parent = ut->mapbase; 1055 printf("RTLD: %p now depends on %p (%s, %d)\n", parent, 1056 ut->handle, ut->name, ut->refcnt); 1057 break; 1058 case UTRACE_PRELOAD_FINISHED: 1059 printf("RTLD: LD_PRELOAD finished\n"); 1060 break; 1061 case UTRACE_INIT_CALL: 1062 printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle, 1063 ut->name); 1064 break; 1065 case UTRACE_FINI_CALL: 1066 printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle, 1067 ut->name); 1068 break; 1069 default: 1070 p += 4; 1071 len -= 4; 1072 printf("RTLD: %d ", len); 1073 while (len--) 1074 if (decimal) 1075 printf(" %d", *p++); 1076 else 1077 printf(" %02x", *p++); 1078 printf("\n"); 1079 } 1080 } 1081 1082 struct utrace_malloc { 1083 void *p; 1084 size_t s; 1085 void *r; 1086 }; 1087 1088 void 1089 ktruser_malloc(int len, unsigned char *p) 1090 { 1091 struct utrace_malloc *ut = (struct utrace_malloc *)p; 1092 1093 if (ut->p == NULL) { 1094 if (ut->s == 0 && ut->r == NULL) 1095 printf("malloc_init()\n"); 1096 else 1097 printf("%p = malloc(%zu)\n", ut->r, ut->s); 1098 } else { 1099 if (ut->s == 0) 1100 printf("free(%p)\n", ut->p); 1101 else 1102 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); 1103 } 1104 } 1105 1106 void 1107 ktruser(int len, unsigned char *p) 1108 { 1109 1110 if (len >= 8 && bcmp(p, "RTLD", 4) == 0) { 1111 ktruser_rtld(len, p); 1112 return; 1113 } 1114 1115 if (len == sizeof(struct utrace_malloc)) { 1116 ktruser_malloc(len, p); 1117 return; 1118 } 1119 1120 (void)printf("%d ", len); 1121 while (len--) 1122 if (decimal) 1123 (void)printf(" %d", *p++); 1124 else 1125 (void)printf(" %02x", *p++); 1126 (void)printf("\n"); 1127 } 1128 1129 void 1130 usage(void) 1131 { 1132 (void)fprintf(stderr, 1133 "usage: kdump [-dEnlHRsT] [-f trfile] [-m maxdata] [-p pid] [-t [cnisuw]]\n"); 1134 exit(1); 1135 } 1136