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