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