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 <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 static const char *ptrace_ops[] = { 306 "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U", 307 "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE", 308 "PT_KILL", "PT_STEP", "PT_ATTACH", "PT_DETACH", 309 }; 310 311 void 312 ktrsyscall(struct ktr_syscall *ktr) 313 { 314 int narg = ktr->ktr_narg; 315 register_t *ip; 316 317 if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) 318 (void)printf("[%d]", ktr->ktr_code); 319 else 320 (void)printf("%s", syscallnames[ktr->ktr_code]); 321 ip = &ktr->ktr_args[0]; 322 if (narg) { 323 char c = '('; 324 if (fancy) { 325 326 #define print_number(i,n,c) do { \ 327 if (decimal) \ 328 (void)printf("%c%ld", c, (long)*i); \ 329 else \ 330 (void)printf("%c%#lx", c, (long)*i); \ 331 i++; \ 332 n--; \ 333 c = ','; \ 334 } while (0); 335 336 if (ktr->ktr_code == SYS_ioctl) { 337 const char *cp; 338 print_number(ip,narg,c); 339 if ((cp = ioctlname(*ip)) != NULL) 340 (void)printf(",%s", cp); 341 else { 342 if (decimal) 343 (void)printf(",%ld", (long)*ip); 344 else 345 (void)printf(",%#lx ", (long)*ip); 346 } 347 c = ','; 348 ip++; 349 narg--; 350 } else if (ktr->ktr_code == SYS_ptrace) { 351 if ((size_t)*ip < sizeof(ptrace_ops) / 352 sizeof(ptrace_ops[0]) && *ip >= 0) 353 (void)printf("(%s", ptrace_ops[*ip]); 354 #ifdef PT_GETREGS 355 else if (*ip == PT_GETREGS) 356 (void)printf("(%s", "PT_GETREGS"); 357 #endif 358 #ifdef PT_SETREGS 359 else if (*ip == PT_SETREGS) 360 (void)printf("(%s", "PT_SETREGS"); 361 #endif 362 #ifdef PT_GETFPREGS 363 else if (*ip == PT_GETFPREGS) 364 (void)printf("(%s", "PT_GETFPREGS"); 365 #endif 366 #ifdef PT_SETFPREGS 367 else if (*ip == PT_SETFPREGS) 368 (void)printf("(%s", "PT_SETFPREGS"); 369 #endif 370 #ifdef PT_GETDBREGS 371 else if (*ip == PT_GETDBREGS) 372 (void)printf("(%s", "PT_GETDBREGS"); 373 #endif 374 #ifdef PT_SETDBREGS 375 else if (*ip == PT_SETDBREGS) 376 (void)printf("(%s", "PT_SETDBREGS"); 377 #endif 378 else 379 (void)printf("(%ld", (long)*ip); 380 c = ','; 381 ip++; 382 narg--; 383 } else if (ktr->ktr_code == SYS_access || 384 ktr->ktr_code == SYS_eaccess) { 385 print_number(ip,narg,c); 386 (void)putchar(','); 387 accessmodename ((int)*ip); 388 ip++; 389 narg--; 390 } else if (ktr->ktr_code == SYS_open) { 391 int flags; 392 int mode; 393 print_number(ip,narg,c); 394 flags = *ip; 395 mode = *++ip; 396 (void)putchar(','); 397 flagsandmodename (flags, mode, decimal); 398 ip++; 399 narg-=2; 400 } else if (ktr->ktr_code == SYS_wait4) { 401 print_number(ip,narg,c); 402 print_number(ip,narg,c); 403 (void)putchar(','); 404 wait4optname ((int)*ip); 405 ip++; 406 narg--; 407 } else if (ktr->ktr_code == SYS_chmod || 408 ktr->ktr_code == SYS_fchmod || 409 ktr->ktr_code == SYS_lchmod) { 410 print_number(ip,narg,c); 411 (void)putchar(','); 412 modename ((int)*ip); 413 ip++; 414 narg--; 415 } else if (ktr->ktr_code == SYS_mknod) { 416 print_number(ip,narg,c); 417 (void)putchar(','); 418 modename ((int)*ip); 419 ip++; 420 narg--; 421 } else if (ktr->ktr_code == SYS_getfsstat) { 422 print_number(ip,narg,c); 423 print_number(ip,narg,c); 424 (void)putchar(','); 425 getfsstatflagsname ((int)*ip); 426 ip++; 427 narg--; 428 } else if (ktr->ktr_code == SYS_mount) { 429 print_number(ip,narg,c); 430 print_number(ip,narg,c); 431 (void)putchar(','); 432 mountflagsname ((int)*ip); 433 ip++; 434 narg--; 435 } else if (ktr->ktr_code == SYS_unmount) { 436 print_number(ip,narg,c); 437 (void)putchar(','); 438 mountflagsname ((int)*ip); 439 ip++; 440 narg--; 441 } else if (ktr->ktr_code == SYS_recvmsg || 442 ktr->ktr_code == SYS_sendmsg) { 443 print_number(ip,narg,c); 444 print_number(ip,narg,c); 445 (void)putchar(','); 446 sendrecvflagsname ((int)*ip); 447 ip++; 448 narg--; 449 } else if (ktr->ktr_code == SYS_recvfrom || 450 ktr->ktr_code == SYS_sendto) { 451 print_number(ip,narg,c); 452 print_number(ip,narg,c); 453 print_number(ip,narg,c); 454 (void)putchar(','); 455 sendrecvflagsname ((int)*ip); 456 ip++; 457 narg--; 458 } else if (ktr->ktr_code == SYS_chflags || 459 ktr->ktr_code == SYS_fchflags || 460 ktr->ktr_code == SYS_lchflags) { 461 print_number(ip,narg,c); 462 (void)putchar(','); 463 modename((int)*ip); 464 ip++; 465 narg--; 466 } else if (ktr->ktr_code == SYS_kill) { 467 print_number(ip,narg,c); 468 (void)putchar(','); 469 signame((int)*ip); 470 ip++; 471 narg--; 472 } else if (ktr->ktr_code == SYS_reboot) { 473 (void)putchar('('); 474 rebootoptname((int)*ip); 475 ip++; 476 narg--; 477 } else if (ktr->ktr_code == SYS_umask) { 478 (void)putchar('('); 479 modename((int)*ip); 480 ip++; 481 narg--; 482 } else if (ktr->ktr_code == SYS_msync) { 483 print_number(ip,narg,c); 484 print_number(ip,narg,c); 485 (void)putchar(','); 486 msyncflagsname((int)*ip); 487 ip++; 488 narg--; 489 } else if (ktr->ktr_code == SYS_mmap) { 490 print_number(ip,narg,c); 491 print_number(ip,narg,c); 492 (void)putchar(','); 493 mmapprotname ((int)*ip); 494 (void)putchar(','); 495 ip++; 496 narg--; 497 mmapflagsname ((int)*ip); 498 ip++; 499 narg--; 500 } else if (ktr->ktr_code == SYS_mprotect) { 501 print_number(ip,narg,c); 502 print_number(ip,narg,c); 503 (void)putchar(','); 504 mmapprotname ((int)*ip); 505 ip++; 506 narg--; 507 } else if (ktr->ktr_code == SYS_madvise) { 508 print_number(ip,narg,c); 509 print_number(ip,narg,c); 510 (void)putchar(','); 511 madvisebehavname((int)*ip); 512 ip++; 513 narg--; 514 } else if (ktr->ktr_code == SYS_setpriority) { 515 print_number(ip,narg,c); 516 print_number(ip,narg,c); 517 (void)putchar(','); 518 prioname((int)*ip); 519 ip++; 520 narg--; 521 } else if (ktr->ktr_code == SYS_fcntl) { 522 int cmd; 523 int arg; 524 print_number(ip,narg,c); 525 cmd = *ip; 526 arg = *++ip; 527 (void)putchar(','); 528 fcntlcmdname(cmd, arg, decimal); 529 ip++; 530 narg-=2; 531 } else if (ktr->ktr_code == SYS_socket) { 532 int sockdomain; 533 (void)putchar('('); 534 sockdomain=(int)*ip; 535 sockdomainname(sockdomain); 536 ip++; 537 narg--; 538 (void)putchar(','); 539 socktypename((int)*ip); 540 ip++; 541 narg--; 542 if (sockdomain == PF_INET || 543 sockdomain == PF_INET6) { 544 (void)putchar(','); 545 sockipprotoname((int)*ip); 546 ip++; 547 narg--; 548 } 549 c = ','; 550 } else if (ktr->ktr_code == SYS_setsockopt || 551 ktr->ktr_code == SYS_getsockopt) { 552 print_number(ip,narg,c); 553 (void)putchar(','); 554 sockoptlevelname((int)*ip, decimal); 555 ip++; 556 narg--; 557 (void)putchar(','); 558 sockoptname((int)*ip); 559 ip++; 560 narg--; 561 } else if (ktr->ktr_code == SYS_lseek) { 562 print_number(ip,narg,c); 563 /* Hidden 'pad' argument, not in lseek(2) */ 564 print_number(ip,narg,c); 565 print_number(ip,narg,c); 566 (void)putchar(','); 567 whencename ((int)*ip); 568 ip++; 569 narg--; 570 } else if (ktr->ktr_code == SYS_flock) { 571 print_number(ip,narg,c); 572 (void)putchar(','); 573 flockname((int)*ip); 574 ip++; 575 narg--; 576 } else if (ktr->ktr_code == SYS_mkfifo || 577 ktr->ktr_code == SYS_mkdir) { 578 print_number(ip,narg,c); 579 (void)putchar(','); 580 modename((int)*ip); 581 ip++; 582 narg--; 583 } else if (ktr->ktr_code == SYS_shutdown) { 584 print_number(ip,narg,c); 585 (void)putchar(','); 586 shutdownhowname((int)*ip); 587 ip++; 588 narg--; 589 } else if (ktr->ktr_code == SYS_socketpair) { 590 (void)putchar('('); 591 sockdomainname((int)*ip); 592 ip++; 593 narg--; 594 (void)putchar(','); 595 socktypename((int)*ip); 596 ip++; 597 narg--; 598 c = ','; 599 } else if (ktr->ktr_code == SYS_getrlimit || 600 ktr->ktr_code == SYS_setrlimit) { 601 (void)putchar('('); 602 rlimitname((int)*ip); 603 ip++; 604 narg--; 605 c = ','; 606 } else if (ktr->ktr_code == SYS_quotactl) { 607 print_number(ip,narg,c); 608 quotactlname((int)*ip); 609 ip++; 610 narg--; 611 c = ','; 612 } else if (ktr->ktr_code == SYS_nfssvc) { 613 (void)putchar('('); 614 nfssvcname((int)*ip); 615 ip++; 616 narg--; 617 c = ','; 618 } else if (ktr->ktr_code == SYS_rtprio) { 619 (void)putchar('('); 620 rtprioname((int)*ip); 621 ip++; 622 narg--; 623 c = ','; 624 } else if (ktr->ktr_code == SYS___semctl) { 625 print_number(ip,narg,c); 626 print_number(ip,narg,c); 627 semctlname((int)*ip); 628 ip++; 629 narg--; 630 } else if (ktr->ktr_code == SYS_semget) { 631 print_number(ip,narg,c); 632 print_number(ip,narg,c); 633 semgetname((int)*ip); 634 ip++; 635 narg--; 636 } else if (ktr->ktr_code == SYS_msgctl) { 637 print_number(ip,narg,c); 638 shmctlname((int)*ip); 639 ip++; 640 narg--; 641 } else if (ktr->ktr_code == SYS_shmat) { 642 print_number(ip,narg,c); 643 print_number(ip,narg,c); 644 shmatname((int)*ip); 645 ip++; 646 narg--; 647 } else if (ktr->ktr_code == SYS_shmctl) { 648 print_number(ip,narg,c); 649 shmctlname((int)*ip); 650 ip++; 651 narg--; 652 } else if (ktr->ktr_code == SYS_minherit) { 653 print_number(ip,narg,c); 654 print_number(ip,narg,c); 655 minheritname((int)*ip); 656 ip++; 657 narg--; 658 } else if (ktr->ktr_code == SYS_rfork) { 659 (void)putchar('('); 660 rforkname((int)*ip); 661 ip++; 662 narg--; 663 c = ','; 664 } else if (ktr->ktr_code == SYS_lio_listio) { 665 (void)putchar('('); 666 lio_listioname((int)*ip); 667 ip++; 668 narg--; 669 c = ','; 670 } else if (ktr->ktr_code == SYS_mlockall) { 671 (void)putchar('('); 672 mlockallname((int)*ip); 673 ip++; 674 narg--; 675 } else if (ktr->ktr_code == SYS_sched_setscheduler) { 676 print_number(ip,narg,c); 677 schedpolicyname((int)*ip); 678 ip++; 679 narg--; 680 } else if (ktr->ktr_code == SYS_sched_get_priority_max || 681 ktr->ktr_code == SYS_sched_get_priority_min) { 682 (void)putchar('('); 683 schedpolicyname((int)*ip); 684 ip++; 685 narg--; 686 } else if (ktr->ktr_code == SYS_sendfile) { 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 print_number(ip,narg,c); 693 sendfileflagsname((int)*ip); 694 ip++; 695 narg--; 696 } else if (ktr->ktr_code == SYS_kldsym) { 697 print_number(ip,narg,c); 698 kldsymcmdname((int)*ip); 699 ip++; 700 narg--; 701 } else if (ktr->ktr_code == SYS_sigprocmask) { 702 (void)putchar('('); 703 sigprocmaskhowname((int)*ip); 704 ip++; 705 narg--; 706 c = ','; 707 } else if (ktr->ktr_code == SYS___acl_get_file || 708 ktr->ktr_code == SYS___acl_set_file || 709 ktr->ktr_code == SYS___acl_get_fd || 710 ktr->ktr_code == SYS___acl_set_fd || 711 ktr->ktr_code == SYS___acl_delete_file || 712 ktr->ktr_code == SYS___acl_delete_fd || 713 ktr->ktr_code == SYS___acl_aclcheck_file || 714 ktr->ktr_code == SYS___acl_aclcheck_fd || 715 ktr->ktr_code == SYS___acl_get_link || 716 ktr->ktr_code == SYS___acl_set_link || 717 ktr->ktr_code == SYS___acl_delete_link || 718 ktr->ktr_code == SYS___acl_aclcheck_link) { 719 print_number(ip,narg,c); 720 acltypename((int)*ip); 721 ip++; 722 narg--; 723 } else if (ktr->ktr_code == SYS_sigaction) { 724 (void)putchar('('); 725 signame((int)*ip); 726 ip++; 727 narg--; 728 c = ','; 729 } else if (ktr->ktr_code == SYS_extattrctl) { 730 print_number(ip,narg,c); 731 extattrctlname((int)*ip); 732 ip++; 733 narg--; 734 } else if (ktr->ktr_code == SYS_nmount) { 735 print_number(ip,narg,c); 736 print_number(ip,narg,c); 737 (void)putchar(','); 738 mountflagsname ((int)*ip); 739 ip++; 740 narg--; 741 } else if (ktr->ktr_code == SYS_kse_thr_interrupt) { 742 print_number(ip,narg,c); 743 (void)putchar(','); 744 ksethrcmdname ((int)*ip); 745 ip++; 746 narg--; 747 } else if (ktr->ktr_code == SYS_thr_create) { 748 print_number(ip,narg,c); 749 print_number(ip,narg,c); 750 (void)putchar(','); 751 thrcreateflagsname ((int)*ip); 752 ip++; 753 narg--; 754 } else if (ktr->ktr_code == SYS_thr_kill) { 755 print_number(ip,narg,c); 756 (void)putchar(','); 757 signame ((int)*ip); 758 ip++; 759 narg--; 760 } else if (ktr->ktr_code == SYS_kldunloadf) { 761 print_number(ip,narg,c); 762 (void)putchar(','); 763 kldunloadfflagsname ((int)*ip); 764 ip++; 765 narg--; 766 } 767 } 768 while (narg) { 769 print_number(ip,narg,c); 770 } 771 (void)putchar(')'); 772 } 773 (void)putchar('\n'); 774 } 775 776 void 777 ktrsysret(struct ktr_sysret *ktr) 778 { 779 register_t ret = ktr->ktr_retval; 780 int error = ktr->ktr_error; 781 int code = ktr->ktr_code; 782 783 if (code >= nsyscalls || code < 0) 784 (void)printf("[%d] ", code); 785 else 786 (void)printf("%s ", syscallnames[code]); 787 788 if (error == 0) { 789 if (fancy) { 790 (void)printf("%d", ret); 791 if (ret < 0 || ret > 9) 792 (void)printf("/%#lx", (long)ret); 793 } else { 794 if (decimal) 795 (void)printf("%ld", (long)ret); 796 else 797 (void)printf("%#lx", (long)ret); 798 } 799 } else if (error == ERESTART) 800 (void)printf("RESTART"); 801 else if (error == EJUSTRETURN) 802 (void)printf("JUSTRETURN"); 803 else { 804 (void)printf("-1 errno %d", ktr->ktr_error); 805 if (fancy) 806 (void)printf(" %s", strerror(ktr->ktr_error)); 807 } 808 (void)putchar('\n'); 809 } 810 811 void 812 ktrnamei(char *cp, int len) 813 { 814 (void)printf("\"%.*s\"\n", len, cp); 815 } 816 817 void 818 hexdump(char *p, int len, int screenwidth) 819 { 820 int n, i; 821 int width; 822 823 width = 0; 824 do { 825 width += 2; 826 i = 13; /* base offset */ 827 i += (width / 2) + 1; /* spaces every second byte */ 828 i += (width * 2); /* width of bytes */ 829 i += 3; /* " |" */ 830 i += width; /* each byte */ 831 i += 1; /* "|" */ 832 } while (i < screenwidth); 833 width -= 2; 834 835 for (n = 0; n < len; n += width) { 836 for (i = n; i < n + width; i++) { 837 if ((i % width) == 0) { /* beginning of line */ 838 printf(" 0x%04x", i); 839 } 840 if ((i % 2) == 0) { 841 printf(" "); 842 } 843 if (i < len) 844 printf("%02x", p[i] & 0xff); 845 else 846 printf(" "); 847 } 848 printf(" |"); 849 for (i = n; i < n + width; i++) { 850 if (i >= len) 851 break; 852 if (p[i] >= ' ' && p[i] <= '~') 853 printf("%c", p[i]); 854 else 855 printf("."); 856 } 857 printf("|\n"); 858 } 859 if ((i % width) != 0) 860 printf("\n"); 861 } 862 863 void 864 visdump(char *dp, int datalen, int screenwidth) 865 { 866 int col = 0; 867 char *cp; 868 int width; 869 char visbuf[5]; 870 871 (void)printf(" \""); 872 col = 8; 873 for (;datalen > 0; datalen--, dp++) { 874 (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 875 cp = visbuf; 876 /* 877 * Keep track of printables and 878 * space chars (like fold(1)). 879 */ 880 if (col == 0) { 881 (void)putchar('\t'); 882 col = 8; 883 } 884 switch(*cp) { 885 case '\n': 886 col = 0; 887 (void)putchar('\n'); 888 continue; 889 case '\t': 890 width = 8 - (col&07); 891 break; 892 default: 893 width = strlen(cp); 894 } 895 if (col + width > (screenwidth-2)) { 896 (void)printf("\\\n\t"); 897 col = 8; 898 } 899 col += width; 900 do { 901 (void)putchar(*cp++); 902 } while (*cp); 903 } 904 if (col == 0) 905 (void)printf(" "); 906 (void)printf("\"\n"); 907 } 908 909 void 910 ktrgenio(struct ktr_genio *ktr, int len) 911 { 912 int datalen = len - sizeof (struct ktr_genio); 913 char *dp = (char *)ktr + sizeof (struct ktr_genio); 914 static int screenwidth = 0; 915 int i, binary; 916 917 if (screenwidth == 0) { 918 struct winsize ws; 919 920 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 921 ws.ws_col > 8) 922 screenwidth = ws.ws_col; 923 else 924 screenwidth = 80; 925 } 926 printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 927 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 928 datalen == 1 ? "" : "s"); 929 if (suppressdata) 930 return; 931 if (maxdata && datalen > maxdata) 932 datalen = maxdata; 933 934 for (i = 0, binary = 0; i < datalen && binary == 0; i++) { 935 if (dp[i] >= 32 && dp[i] < 127) 936 continue; 937 if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9) 938 continue; 939 binary = 1; 940 } 941 if (binary) 942 hexdump(dp, datalen, screenwidth); 943 else 944 visdump(dp, datalen, screenwidth); 945 } 946 947 const char *signames[] = { 948 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 949 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 950 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 951 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 952 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 953 "USR2", NULL, /* 31 - 32 */ 954 }; 955 956 void 957 ktrpsig(struct ktr_psig *psig) 958 { 959 if (psig->signo > 0 && psig->signo < NSIG) 960 (void)printf("SIG%s ", signames[psig->signo]); 961 else 962 (void)printf("SIG %d ", psig->signo); 963 if (psig->action == SIG_DFL) 964 (void)printf("SIG_DFL\n"); 965 else { 966 (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 967 (u_long)psig->action, psig->mask.__bits[0], psig->code); 968 } 969 } 970 971 void 972 ktrcsw(struct ktr_csw *cs) 973 { 974 (void)printf("%s %s\n", cs->out ? "stop" : "resume", 975 cs->user ? "user" : "kernel"); 976 } 977 978 struct utrace_malloc { 979 void *p; 980 size_t s; 981 void *r; 982 }; 983 984 void 985 ktruser_malloc(int len, unsigned char *p) 986 { 987 struct utrace_malloc *ut = (struct utrace_malloc *)p; 988 989 if (ut->p == NULL) { 990 if (ut->s == 0 && ut->r == NULL) 991 printf("malloc_init()\n"); 992 else 993 printf("%p = malloc(%zu)\n", ut->r, ut->s); 994 } else { 995 if (ut->s == 0) 996 printf("free(%p)\n", ut->p); 997 else 998 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); 999 } 1000 } 1001 1002 void 1003 ktruser(int len, unsigned char *p) 1004 { 1005 1006 if (len == sizeof(struct utrace_malloc)) { 1007 ktruser_malloc(len, p); 1008 return; 1009 } 1010 1011 (void)printf("%d ", len); 1012 while (len--) 1013 if (decimal) 1014 (void)printf(" %d", *p++); 1015 else 1016 (void)printf(" %02x", *p++); 1017 (void)printf("\n"); 1018 } 1019 1020 void 1021 usage(void) 1022 { 1023 (void)fprintf(stderr, 1024 "usage: kdump [-dEnlHRsT] [-f trfile] [-m maxdata] [-p pid] [-t [cnisuw]]\n"); 1025 exit(1); 1026 } 1027