1 /* $OpenBSD: kdump.c,v 1.51 2011/06/20 17:54:48 otto Exp $ */ 2 3 /*- 4 * Copyright (c) 1988, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/param.h> 33 #include <sys/time.h> 34 #include <sys/uio.h> 35 #include <sys/ktrace.h> 36 #include <sys/ioctl.h> 37 #include <sys/ptrace.h> 38 #include <sys/socket.h> 39 #include <sys/sysctl.h> 40 #define _KERNEL 41 #include <sys/errno.h> 42 #undef _KERNEL 43 44 #include <ctype.h> 45 #include <err.h> 46 #include <signal.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <unistd.h> 51 #include <vis.h> 52 53 #include "ktrace.h" 54 #include "kdump.h" 55 #include "kdump_subr.h" 56 #include "extern.h" 57 58 int timestamp, decimal, iohex, fancy = 1, tail, maxdata; 59 char *tracefile = DEF_TRACEFILE; 60 struct ktr_header ktr_header; 61 pid_t pid = -1; 62 63 #define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 64 65 #include <sys/syscall.h> 66 67 #include <compat/linux/linux_syscall.h> 68 #include <compat/svr4/svr4_syscall.h> 69 70 #define KTRACE 71 #define PTRACE 72 #define NFSCLIENT 73 #define NFSSERVER 74 #define SYSVSEM 75 #define SYSVMSG 76 #define SYSVSHM 77 #define LFS 78 #include <kern/syscalls.c> 79 80 #include <compat/linux/linux_syscalls.c> 81 #include <compat/svr4/svr4_syscalls.c> 82 #undef KTRACE 83 #undef PTRACE 84 #undef NFSCLIENT 85 #undef NFSSERVER 86 #undef SYSVSEM 87 #undef SYSVMSG 88 #undef SYSVSHM 89 #undef LFS 90 91 struct emulation { 92 char *name; /* Emulation name */ 93 char **sysnames; /* Array of system call names */ 94 int nsysnames; /* Number of */ 95 }; 96 97 static struct emulation emulations[] = { 98 { "native", syscallnames, SYS_MAXSYSCALL }, 99 { "linux", linux_syscallnames, LINUX_SYS_MAXSYSCALL }, 100 { "svr4", svr4_syscallnames, SVR4_SYS_MAXSYSCALL }, 101 { NULL, NULL, 0 } 102 }; 103 104 struct emulation *current; 105 106 107 static char *ptrace_ops[] = { 108 "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U", 109 "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE", 110 "PT_KILL", "PT_ATTACH", "PT_DETACH", "PT_IO", 111 }; 112 113 static int fread_tail(void *, size_t, size_t); 114 static void dumpheader(struct ktr_header *); 115 static void ktrcsw(struct ktr_csw *); 116 static void ktremul(char *, size_t); 117 static void ktrgenio(struct ktr_genio *, size_t); 118 static void ktrnamei(const char *, size_t); 119 static void ktrpsig(struct ktr_psig *); 120 static void ktrsyscall(struct ktr_syscall *); 121 static void ktrsysret(struct ktr_sysret *); 122 static void setemul(const char *); 123 static void usage(void); 124 125 int 126 main(int argc, char *argv[]) 127 { 128 int ch, silent; 129 size_t ktrlen, size; 130 int trpoints = ALL_POINTS; 131 void *m; 132 133 current = &emulations[0]; /* native */ 134 135 while ((ch = getopt(argc, argv, "e:f:dlm:nRp:Tt:xX")) != -1) 136 switch (ch) { 137 case 'e': 138 setemul(optarg); 139 break; 140 case 'f': 141 tracefile = optarg; 142 break; 143 case 'd': 144 decimal = 1; 145 break; 146 case 'l': 147 tail = 1; 148 break; 149 case 'm': 150 maxdata = atoi(optarg); 151 break; 152 case 'n': 153 fancy = 0; 154 break; 155 case 'p': 156 pid = atoi(optarg); 157 break; 158 case 'R': 159 timestamp = 2; /* relative timestamp */ 160 break; 161 case 'T': 162 timestamp = 1; 163 break; 164 case 't': 165 trpoints = getpoints(optarg); 166 if (trpoints < 0) 167 errx(1, "unknown trace point in %s", optarg); 168 break; 169 case 'x': 170 iohex = 1; 171 break; 172 case 'X': 173 iohex = 2; 174 break; 175 default: 176 usage(); 177 } 178 if (argc > optind) 179 usage(); 180 181 m = malloc(size = 1025); 182 if (m == NULL) 183 err(1, NULL); 184 if (!freopen(tracefile, "r", stdin)) 185 err(1, "%s", tracefile); 186 while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 187 silent = 0; 188 if (pid != -1 && pid != ktr_header.ktr_pid) 189 silent = 1; 190 if (silent == 0 && trpoints & (1<<ktr_header.ktr_type)) 191 dumpheader(&ktr_header); 192 ktrlen = ktr_header.ktr_len; 193 if (ktrlen > size) { 194 void *newm; 195 196 newm = realloc(m, ktrlen+1); 197 if (newm == NULL) 198 err(1, NULL); 199 m = newm; 200 size = ktrlen; 201 } 202 if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 203 errx(1, "data too short"); 204 if (silent) 205 continue; 206 if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 207 continue; 208 switch (ktr_header.ktr_type) { 209 case KTR_SYSCALL: 210 ktrsyscall((struct ktr_syscall *)m); 211 break; 212 case KTR_SYSRET: 213 ktrsysret((struct ktr_sysret *)m); 214 break; 215 case KTR_NAMEI: 216 ktrnamei(m, ktrlen); 217 break; 218 case KTR_GENIO: 219 ktrgenio((struct ktr_genio *)m, ktrlen); 220 break; 221 case KTR_PSIG: 222 ktrpsig((struct ktr_psig *)m); 223 break; 224 case KTR_CSW: 225 ktrcsw((struct ktr_csw *)m); 226 break; 227 case KTR_EMUL: 228 ktremul(m, ktrlen); 229 break; 230 } 231 if (tail) 232 (void)fflush(stdout); 233 } 234 exit(0); 235 } 236 237 static int 238 fread_tail(void *buf, size_t size, size_t num) 239 { 240 int i; 241 242 while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 243 (void)sleep(1); 244 clearerr(stdin); 245 } 246 return (i); 247 } 248 249 static void 250 dumpheader(struct ktr_header *kth) 251 { 252 static struct timeval prevtime; 253 char unknown[64], *type; 254 struct timeval temp; 255 256 switch (kth->ktr_type) { 257 case KTR_SYSCALL: 258 type = "CALL"; 259 break; 260 case KTR_SYSRET: 261 type = "RET "; 262 break; 263 case KTR_NAMEI: 264 type = "NAMI"; 265 break; 266 case KTR_GENIO: 267 type = "GIO "; 268 break; 269 case KTR_PSIG: 270 type = "PSIG"; 271 break; 272 case KTR_CSW: 273 type = "CSW"; 274 break; 275 case KTR_EMUL: 276 type = "EMUL"; 277 break; 278 default: 279 (void)snprintf(unknown, sizeof unknown, "UNKNOWN(%d)", 280 kth->ktr_type); 281 type = unknown; 282 } 283 284 (void)printf("%6ld %-8.*s ", (long)kth->ktr_pid, MAXCOMLEN, 285 kth->ktr_comm); 286 if (timestamp) { 287 if (timestamp == 2) { 288 timersub(&kth->ktr_time, &prevtime, &temp); 289 prevtime = kth->ktr_time; 290 } else 291 temp = kth->ktr_time; 292 (void)printf("%ld.%06ld ", temp.tv_sec, temp.tv_usec); 293 } 294 (void)printf("%s ", type); 295 } 296 297 static void 298 ioctldecode(u_long cmd) 299 { 300 char dirbuf[4], *dir = dirbuf; 301 302 if (cmd & IOC_IN) 303 *dir++ = 'W'; 304 if (cmd & IOC_OUT) 305 *dir++ = 'R'; 306 *dir = '\0'; 307 308 printf(decimal ? ",_IO%s('%c',%lu" : ",_IO%s('%c',%#lx", 309 dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff); 310 if ((cmd & IOC_VOID) == 0) 311 printf(decimal ? ",%lu)" : ",%#lx)", (cmd >> 16) & 0xff); 312 else 313 printf(")"); 314 } 315 316 #define print_number(i, n, c) do { \ 317 if (c) \ 318 (void)putchar(c); \ 319 if (decimal) \ 320 (void)printf("%ld", (long)*i); \ 321 else \ 322 (void)printf("%#lx", (long)*i); \ 323 i++; \ 324 n--; \ 325 c = ','; \ 326 } while (0); 327 328 static void 329 ktrsyscall(struct ktr_syscall *ktr) 330 { 331 int narg = ktr->ktr_argsize / sizeof(register_t); 332 register_t *ap; 333 334 if (ktr->ktr_code >= current->nsysnames || ktr->ktr_code < 0) 335 (void)printf("[%d]", ktr->ktr_code); 336 else 337 (void)printf("%s", current->sysnames[ktr->ktr_code]); 338 ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall)); 339 (void)putchar('('); 340 if (narg) { 341 char c = '\0'; 342 if (fancy) { 343 switch (ktr->ktr_code) { 344 case SYS_ioctl: { 345 const char *cp; 346 347 if (decimal) 348 (void)printf("%ld", (long)*ap); 349 else 350 (void)printf("%#lx", (long)*ap); 351 ap++; 352 narg--; 353 if ((cp = ioctlname(*ap)) != NULL) 354 (void)printf(",%s", cp); 355 else 356 ioctldecode(*ap); 357 c = ','; 358 ap++; 359 narg--; 360 break; 361 } 362 case SYS___sysctl: { 363 int *np, n; 364 365 n = ap[1]; 366 if (n > CTL_MAXNAME) 367 n = CTL_MAXNAME; 368 np = (int *)(ap + 6); 369 for (; n--; np++) { 370 if (c) 371 putchar(c); 372 printf("%d", *np); 373 c = '.'; 374 } 375 376 c = ','; 377 ap += 2; 378 narg -= 2; 379 break; 380 } 381 case SYS_ptrace: 382 if (*ap >= 0 && *ap < 383 sizeof(ptrace_ops) / sizeof(ptrace_ops[0])) 384 (void)printf("%s", ptrace_ops[*ap]); 385 else switch(*ap) { 386 #ifdef PT_GETFPREGS 387 case PT_GETFPREGS: 388 (void)printf("PT_GETFPREGS"); 389 break; 390 #endif 391 case PT_GETREGS: 392 (void)printf("PT_GETREGS"); 393 break; 394 #ifdef PT_SETFPREGS 395 case PT_SETFPREGS: 396 (void)printf("PT_SETFPREGS"); 397 break; 398 #endif 399 case PT_SETREGS: 400 (void)printf("PT_SETREGS"); 401 break; 402 #ifdef PT_STEP 403 case PT_STEP: 404 (void)printf("PT_STEP"); 405 break; 406 #endif 407 #ifdef PT_WCOOKIE 408 case PT_WCOOKIE: 409 (void)printf("PT_WCOOKIE"); 410 break; 411 #endif 412 default: 413 (void)printf("%ld", (long)*ap); 414 break; 415 } 416 c = ','; 417 ap++; 418 narg--; 419 break; 420 case SYS_access: 421 print_number(ap, narg, c); 422 (void)putchar(','); 423 accessmodename((int)*ap); 424 ap++; 425 narg--; 426 break; 427 case SYS_chmod: 428 case SYS_fchmod: 429 print_number(ap, narg, c); 430 (void)putchar(','); 431 modename((int)*ap); 432 ap++; 433 narg--; 434 break; 435 case SYS_fcntl: { 436 int cmd; 437 int arg; 438 print_number(ap, narg, c); 439 cmd = *ap; 440 arg = *++ap; 441 (void)putchar(','); 442 fcntlcmdname(cmd, arg, decimal); 443 ap++; 444 narg -= 2; 445 break; 446 } 447 case SYS_flock: 448 print_number(ap, narg, c); 449 (void)putchar(','); 450 flockname((int)*ap); 451 ap++; 452 narg--; 453 break; 454 case SYS_getrlimit: 455 case SYS_setrlimit: 456 rlimitname((int)*ap); 457 ap++; 458 narg--; 459 c = ','; 460 break; 461 case SYS_getsockopt: 462 case SYS_setsockopt: 463 print_number(ap, narg, c); 464 (void)putchar(','); 465 sockoptlevelname((int)*ap, decimal); 466 if ((int)*ap == SOL_SOCKET) { 467 ap++; 468 narg--; 469 (void)putchar(','); 470 sockoptname((int)*ap); 471 } 472 ap++; 473 narg--; 474 break; 475 case SYS_kill: 476 print_number(ap, narg, c); 477 (void)putchar(','); 478 signame((int)*ap); 479 ap++; 480 narg--; 481 break; 482 case SYS_lseek: 483 print_number(ap, narg, c); 484 /* skip padding */ 485 ap++; 486 narg--; 487 print_number(ap, narg, c); 488 (void)putchar(','); 489 whencename((int)*ap); 490 ap++; 491 narg--; 492 break; 493 case SYS_madvise: 494 print_number(ap, narg, c); 495 print_number(ap, narg, c); 496 (void)putchar(','); 497 madvisebehavname((int)*ap); 498 ap++; 499 narg--; 500 break; 501 case SYS_minherit: 502 print_number(ap, narg, c); 503 print_number(ap, narg, c); 504 (void)putchar(','); 505 minheritname((int)*ap); 506 ap++; 507 narg--; 508 break; 509 case SYS_mlockall: 510 mlockallname((int)*ap); 511 ap++; 512 narg--; 513 break; 514 case SYS_mmap: 515 print_number(ap, narg, c); 516 print_number(ap, narg, c); 517 (void)putchar(','); 518 mmapprotname((int)*ap); 519 (void)putchar(','); 520 ap++; 521 narg--; 522 mmapflagsname((int)*ap); 523 ap++; 524 narg--; 525 print_number(ap, narg, c); 526 /* skip padding */ 527 ap++; 528 narg--; 529 break; 530 case SYS_mprotect: 531 print_number(ap, narg, c); 532 print_number(ap, narg, c); 533 (void)putchar(','); 534 mmapprotname((int)*ap); 535 ap++; 536 narg--; 537 break; 538 case SYS_mquery: 539 print_number(ap, narg, c); 540 print_number(ap, narg, c); 541 (void)putchar(','); 542 mmapprotname((int)*ap); 543 ap++; 544 narg--; 545 (void)putchar(','); 546 mmapflagsname((int)*ap); 547 ap++; 548 narg--; 549 print_number(ap, narg, c); 550 /* skip padding */ 551 ap++; 552 narg--; 553 break; 554 case SYS_msync: 555 print_number(ap, narg, c); 556 print_number(ap, narg, c); 557 (void)putchar(','); 558 msyncflagsname((int)*ap); 559 ap++; 560 narg--; 561 break; 562 case SYS_msgctl: 563 print_number(ap, narg, c); 564 (void)putchar(','); 565 shmctlname((int)*ap); 566 ap++; 567 narg--; 568 break; 569 case SYS_open: { 570 int flags; 571 int mode; 572 print_number(ap, narg, c); 573 flags = *ap; 574 mode = *++ap; 575 (void)putchar(','); 576 flagsandmodename(flags, mode, decimal); 577 ap++; 578 narg -= 2; 579 break; 580 } 581 case SYS_pread: 582 case SYS_preadv: 583 case SYS_pwrite: 584 case SYS_pwritev: 585 print_number(ap, narg, c); 586 print_number(ap, narg, c); 587 print_number(ap, narg, c); 588 /* skip padding */ 589 ap++; 590 narg--; 591 break; 592 case SYS_recvmsg: 593 case SYS_sendmsg: 594 print_number(ap, narg, c); 595 print_number(ap, narg, c); 596 (void)putchar(','); 597 sendrecvflagsname((int)*ap); 598 ap++; 599 narg--; 600 break; 601 case SYS_recvfrom: 602 case SYS_sendto: 603 print_number(ap, narg, c); 604 print_number(ap, narg, c); 605 print_number(ap, narg, c); 606 (void)putchar(','); 607 sendrecvflagsname((int)*ap); 608 ap++; 609 narg--; 610 break; 611 case SYS___semctl: 612 print_number(ap, narg, c); 613 print_number(ap, narg, c); 614 (void)putchar(','); 615 semctlname((int)*ap); 616 ap++; 617 narg--; 618 break; 619 case SYS_semget: 620 print_number(ap, narg, c); 621 print_number(ap, narg, c); 622 (void)putchar(','); 623 semgetname((int)*ap); 624 ap++; 625 narg--; 626 break; 627 case SYS_shmat: 628 print_number(ap, narg, c); 629 print_number(ap, narg, c); 630 (void)putchar(','); 631 shmatname((int)*ap); 632 ap++; 633 narg--; 634 break; 635 case SYS_shmctl: 636 print_number(ap, narg, c); 637 (void)putchar(','); 638 shmctlname((int)*ap); 639 ap++; 640 narg--; 641 break; 642 case SYS_sigaction: 643 signame((int)*ap); 644 ap++; 645 narg--; 646 c = ','; 647 break; 648 case SYS_sigprocmask: 649 sigprocmaskhowname((int)*ap); 650 ap++; 651 narg--; 652 c = ','; 653 break; 654 case SYS_socket: { 655 int sockdomain = (int)*ap; 656 sockdomainname(sockdomain); 657 ap++; 658 narg--; 659 (void)putchar(','); 660 socktypename((int)*ap); 661 ap++; 662 narg--; 663 if (sockdomain == PF_INET || 664 sockdomain == PF_INET6) { 665 (void)putchar(','); 666 sockipprotoname((int)*ap); 667 ap++; 668 narg--; 669 } 670 c = ','; 671 break; 672 } 673 case SYS_socketpair: 674 sockdomainname((int)*ap); 675 ap++; 676 narg--; 677 (void)putchar(','); 678 socktypename((int)*ap); 679 ap++; 680 narg--; 681 c = ','; 682 break; 683 case SYS_truncate: 684 case SYS_ftruncate: 685 print_number(ap, narg, c); 686 /* skip padding */ 687 ap++; 688 narg--; 689 break; 690 case SYS_wait4: 691 print_number(ap, narg, c); 692 print_number(ap, narg, c); 693 (void)putchar(','); 694 wait4optname((int)*ap); 695 ap++; 696 narg--; 697 break; 698 } 699 } 700 while (narg) { 701 if (c) 702 putchar(c); 703 if (decimal) 704 (void)printf("%ld", (long)*ap); 705 else 706 (void)printf("%#lx", (long)*ap); 707 c = ','; 708 ap++; 709 narg--; 710 } 711 } 712 (void)printf(")\n"); 713 } 714 715 static void 716 ktrsysret(struct ktr_sysret *ktr) 717 { 718 register_t ret = ktr->ktr_retval; 719 int error = ktr->ktr_error; 720 int code = ktr->ktr_code; 721 722 if (code >= current->nsysnames || code < 0) 723 (void)printf("[%d] ", code); 724 else 725 (void)printf("%s ", current->sysnames[code]); 726 727 if (error == 0) { 728 if (fancy) { 729 (void)printf("%ld", (long)ret); 730 if (ret < 0 || ret > 9) 731 (void)printf("/%#lx", (long)ret); 732 } else { 733 if (decimal) 734 (void)printf("%ld", (long)ret); 735 else 736 (void)printf("%#lx", (long)ret); 737 } 738 } else if (error == ERESTART) 739 (void)printf("RESTART"); 740 else if (error == EJUSTRETURN) 741 (void)printf("JUSTRETURN"); 742 else { 743 (void)printf("-1 errno %d", ktr->ktr_error); 744 if (fancy) 745 (void)printf(" %s", strerror(ktr->ktr_error)); 746 } 747 (void)putchar('\n'); 748 } 749 750 static void 751 ktrnamei(const char *cp, size_t len) 752 { 753 (void)printf("\"%.*s\"\n", (int)len, cp); 754 } 755 756 static void 757 ktremul(char *cp, size_t len) 758 { 759 char name[1024]; 760 761 if (len >= sizeof(name)) 762 errx(1, "Emulation name too long"); 763 764 strncpy(name, cp, len); 765 name[len] = '\0'; 766 (void)printf("\"%s\"\n", name); 767 768 setemul(name); 769 } 770 771 static void 772 ktrgenio(struct ktr_genio *ktr, size_t len) 773 { 774 unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio); 775 int i, j; 776 size_t datalen = len - sizeof(struct ktr_genio); 777 static int screenwidth = 0; 778 int col = 0, width, bpl; 779 unsigned char visbuf[5], *cp, c; 780 781 if (screenwidth == 0) { 782 struct winsize ws; 783 784 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 785 ws.ws_col > 8) 786 screenwidth = ws.ws_col; 787 else 788 screenwidth = 80; 789 } 790 printf("fd %d %s %zu bytes\n", ktr->ktr_fd, 791 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen); 792 if (maxdata && datalen > maxdata) 793 datalen = maxdata; 794 if (iohex && !datalen) 795 return; 796 if (iohex == 1) { 797 putchar('\t'); 798 col = 8; 799 for (i = 0; i < datalen; i++) { 800 printf("%02x", dp[i]); 801 col += 3; 802 if (i < datalen - 1) { 803 if (col + 3 > screenwidth) { 804 printf("\n\t"); 805 col = 8; 806 } else 807 putchar(' '); 808 } 809 } 810 putchar('\n'); 811 return; 812 } 813 if (iohex == 2) { 814 bpl = (screenwidth - 13)/4; 815 if (bpl <= 0) 816 bpl = 1; 817 for (i = 0; i < datalen; i += bpl) { 818 printf(" %04x: ", i); 819 for (j = 0; j < bpl; j++) { 820 if (i+j >= datalen) 821 printf(" "); 822 else 823 printf("%02x ", dp[i+j]); 824 } 825 putchar(' '); 826 for (j = 0; j < bpl; j++) { 827 if (i+j >= datalen) 828 break; 829 c = dp[i+j]; 830 if (!isprint(c)) 831 c = '.'; 832 putchar(c); 833 } 834 putchar('\n'); 835 } 836 return; 837 } 838 (void)printf(" \""); 839 col = 8; 840 for (; datalen > 0; datalen--, dp++) { 841 (void)vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 842 cp = visbuf; 843 844 /* 845 * Keep track of printables and 846 * space chars (like fold(1)). 847 */ 848 if (col == 0) { 849 (void)putchar('\t'); 850 col = 8; 851 } 852 switch (*cp) { 853 case '\n': 854 col = 0; 855 (void)putchar('\n'); 856 continue; 857 case '\t': 858 width = 8 - (col&07); 859 break; 860 default: 861 width = strlen(cp); 862 } 863 if (col + width > (screenwidth-2)) { 864 (void)printf("\\\n\t"); 865 col = 8; 866 } 867 col += width; 868 do { 869 (void)putchar(*cp++); 870 } while (*cp); 871 } 872 if (col == 0) 873 (void)printf(" "); 874 (void)printf("\"\n"); 875 } 876 877 static void 878 ktrpsig(struct ktr_psig *psig) 879 { 880 (void)printf("SIG%s ", sys_signame[psig->signo]); 881 if (psig->action == SIG_DFL) 882 (void)printf("SIG_DFL code %d", psig->code); 883 else 884 (void)printf("caught handler=0x%lx mask=0x%x", 885 (u_long)psig->action, psig->mask); 886 switch (psig->signo) { 887 case SIGSEGV: 888 case SIGILL: 889 case SIGBUS: 890 case SIGFPE: 891 printf(" addr=%p trapno=%d", psig->si.si_addr, 892 psig->si.si_trapno); 893 break; 894 default: 895 break; 896 } 897 printf("\n"); 898 } 899 900 static void 901 ktrcsw(struct ktr_csw *cs) 902 { 903 (void)printf("%s %s\n", cs->out ? "stop" : "resume", 904 cs->user ? "user" : "kernel"); 905 } 906 907 static void 908 usage(void) 909 { 910 911 extern char *__progname; 912 fprintf(stderr, "usage: %s " 913 "[-dlnRTXx] [-e emulation] [-f file] [-m maxdata] [-p pid]\n" 914 "%*s[-t [ceinsw]]\n", 915 __progname, (int)(sizeof("usage: ") + strlen(__progname)), ""); 916 exit(1); 917 } 918 919 static void 920 setemul(const char *name) 921 { 922 int i; 923 924 for (i = 0; emulations[i].name != NULL; i++) 925 if (strcmp(emulations[i].name, name) == 0) { 926 current = &emulations[i]; 927 return; 928 } 929 warnx("Emulation `%s' unknown", name); 930 } 931