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 * @(#) Copyright (c) 1988, 1993 The Regents of the University of California. All rights reserved. 34 * @(#)kdump.c 8.1 (Berkeley) 6/6/93 35 * $FreeBSD: src/usr.bin/kdump/kdump.c,v 1.29 2006/05/20 14:27:22 netchild Exp $ 36 * $DragonFly: src/usr.bin/kdump/kdump.c,v 1.13 2008/10/16 01:52:32 swildner Exp $ 37 */ 38 39 #define _KERNEL_STRUCTURES 40 41 #include <sys/errno.h> 42 #include <sys/param.h> 43 #include <sys/errno.h> 44 #include <sys/time.h> 45 #include <sys/uio.h> 46 #include <sys/ktrace.h> 47 #include <sys/ioctl.h> 48 #include <sys/ptrace.h> 49 #include <err.h> 50 #include <locale.h> 51 #include <stdio.h> 52 #include <stdlib.h> 53 #include <string.h> 54 #include <unistd.h> 55 #include <vis.h> 56 #include "ktrace.h" 57 #include "kdump_subr.h" 58 59 int timestamp, decimal, fancy = 1, tail, maxdata = 64; 60 int fixedformat; 61 char *tracefile = DEF_TRACEFILE; 62 struct ktr_header ktr_header; 63 64 #define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 65 66 main(int argc, char **argv) 67 { 68 int ch, col, ktrlen, size; 69 pid_t do_pid = -1; 70 void *m; 71 int trpoints = ALL_POINTS; 72 char *cp; 73 74 (void) setlocale(LC_CTYPE, ""); 75 76 while ((ch = getopt(argc,argv,"f:djlm:np:RTt:")) != -1) 77 switch((char)ch) { 78 case 'f': 79 tracefile = optarg; 80 break; 81 case 'j': 82 fixedformat = 1; 83 break; 84 case 'd': 85 decimal = 1; 86 break; 87 case 'l': 88 tail = 1; 89 break; 90 case 'm': 91 maxdata = atoi(optarg); 92 break; 93 case 'n': 94 fancy = 0; 95 break; 96 case 'p': 97 do_pid = strtoul(optarg, &cp, 0); 98 if (*cp != 0) 99 errx(1,"invalid number %s", optarg); 100 break; 101 case 'R': 102 timestamp = 2; /* relative timestamp */ 103 break; 104 case 'T': 105 timestamp = 1; 106 break; 107 case 't': 108 trpoints = getpoints(optarg); 109 if (trpoints < 0) 110 errx(1, "unknown trace point in %s", optarg); 111 break; 112 default: 113 usage(); 114 } 115 116 if (argc > optind) 117 usage(); 118 119 m = (void *)malloc(size = 1025); 120 if (m == NULL) 121 errx(1, "%s", strerror(ENOMEM)); 122 if (!freopen(tracefile, "r", stdin)) 123 err(1, "%s", tracefile); 124 while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 125 if (trpoints & (1 << ktr_header.ktr_type) && 126 (do_pid == -1 || ktr_header.ktr_pid == do_pid)) 127 col = dumpheader(&ktr_header); 128 else 129 col = -1; 130 if ((ktrlen = ktr_header.ktr_len) < 0) 131 errx(1, "bogus length 0x%x", ktrlen); 132 if (ktrlen > size) { 133 m = (void *)realloc(m, ktrlen+1); 134 if (m == NULL) 135 errx(1, "%s", strerror(ENOMEM)); 136 size = ktrlen; 137 } 138 if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 139 errx(1, "data too short"); 140 if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 141 continue; 142 if (col == -1) 143 continue; 144 switch (ktr_header.ktr_type) { 145 case KTR_SYSCALL: 146 ktrsyscall((struct ktr_syscall *)m); 147 break; 148 case KTR_SYSRET: 149 ktrsysret((struct ktr_sysret *)m); 150 break; 151 case KTR_NAMEI: 152 ktrnamei(m, ktrlen); 153 break; 154 case KTR_GENIO: 155 ktrgenio((struct ktr_genio *)m, ktrlen); 156 break; 157 case KTR_PSIG: 158 ktrpsig((struct ktr_psig *)m); 159 break; 160 case KTR_CSW: 161 ktrcsw((struct ktr_csw *)m); 162 break; 163 case KTR_USER: 164 ktruser(ktrlen, m); 165 break; 166 } 167 if (tail) 168 (void)fflush(stdout); 169 } 170 } 171 172 fread_tail(char *buf, int size, int num) 173 { 174 int i; 175 176 while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 177 (void)sleep(1); 178 clearerr(stdin); 179 } 180 return (i); 181 } 182 183 dumpheader(struct ktr_header *kth) 184 { 185 static char unknown[64]; 186 static struct timeval prevtime, temp; 187 char *type; 188 int col; 189 190 switch (kth->ktr_type) { 191 case KTR_SYSCALL: 192 type = "CALL"; 193 break; 194 case KTR_SYSRET: 195 type = "RET "; 196 break; 197 case KTR_NAMEI: 198 type = "NAMI"; 199 break; 200 case KTR_GENIO: 201 type = "GIO "; 202 break; 203 case KTR_PSIG: 204 type = "PSIG"; 205 break; 206 case KTR_CSW: 207 type = "CSW"; 208 break; 209 case KTR_USER: 210 type = "USER"; 211 break; 212 default: 213 (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 214 type = unknown; 215 } 216 217 if (kth->ktr_tid || (kth->ktr_flags & KTRH_THREADED) || fixedformat) 218 col = printf("%5d:%-4d", kth->ktr_pid, kth->ktr_tid); 219 else 220 col = printf("%5d", kth->ktr_pid); 221 col += printf(" %-8.*s ", MAXCOMLEN, kth->ktr_comm); 222 if (timestamp) { 223 if (timestamp == 2) { 224 temp = kth->ktr_time; 225 timevalsub(&kth->ktr_time, &prevtime); 226 prevtime = temp; 227 } 228 col += printf("%ld.%06ld ", 229 kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); 230 } 231 col += printf("%s ", type); 232 return col; 233 } 234 235 #include <sys/syscall.h> 236 #define KTRACE 237 #include <sys/kern/syscalls.c> 238 #undef KTRACE 239 int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 240 241 static char *ptrace_ops[] = { 242 "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U", 243 "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE", 244 "PT_KILL", "PT_STEP", "PT_ATTACH", "PT_DETACH", 245 }; 246 247 ktrsyscall(struct ktr_syscall *ktr) 248 { 249 int narg = ktr->ktr_narg; 250 register_t *ip; 251 char *ioctlname(); 252 253 if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) 254 (void)printf("[%d]", ktr->ktr_code); 255 else 256 (void)printf("%s", syscallnames[ktr->ktr_code]); 257 ip = &ktr->ktr_args[0]; 258 if (narg) { 259 char c = '('; 260 if (fancy) { 261 262 #define print_number(i,n,c) do { \ 263 if (decimal) \ 264 (void)printf("%c%ld", c, (long)*i); \ 265 else \ 266 (void)printf("%c%#lx", c, (long)*i); \ 267 i++; \ 268 n--; \ 269 c = ','; \ 270 } while (0); 271 272 if (ktr->ktr_code == SYS_ioctl) { 273 char *cp; 274 print_number(ip,narg,c); 275 if ((cp = ioctlname(*ip)) != NULL) 276 (void)printf(",%s", cp); 277 else { 278 if (decimal) 279 (void)printf(",%ld", (long)*ip); 280 else 281 (void)printf(",%#lx ", (long)*ip); 282 } 283 c = ','; 284 ip++; 285 narg--; 286 } else if (ktr->ktr_code == SYS_access) { 287 print_number(ip,narg,c); 288 (void)putchar(','); 289 accessmodename ((int)*ip); 290 ip++; 291 narg--; 292 } else if (ktr->ktr_code == SYS_open) { 293 int flags; 294 int mode; 295 print_number(ip,narg,c); 296 flags = *ip; 297 mode = *++ip; 298 (void)putchar(','); 299 flagsandmodename (flags, mode, decimal); 300 ip++; 301 narg-=2; 302 } else if (ktr->ktr_code == SYS_wait4) { 303 print_number(ip,narg,c); 304 print_number(ip,narg,c); 305 (void)putchar(','); 306 wait4optname ((int)*ip); 307 ip++; 308 narg--; 309 } else if (ktr->ktr_code == SYS_chmod || 310 ktr->ktr_code == SYS_fchmod || 311 ktr->ktr_code == SYS_lchmod) { 312 print_number(ip,narg,c); 313 (void)putchar(','); 314 modename ((int)*ip); 315 ip++; 316 narg--; 317 } else if (ktr->ktr_code == SYS_mknod) { 318 print_number(ip,narg,c); 319 (void)putchar(','); 320 modename ((int)*ip); 321 ip++; 322 narg--; 323 } else if (ktr->ktr_code == SYS_getfsstat) { 324 print_number(ip,narg,c); 325 print_number(ip,narg,c); 326 (void)putchar(','); 327 getfsstatflagsname ((int)*ip); 328 ip++; 329 narg--; 330 } else if (ktr->ktr_code == SYS_mount) { 331 print_number(ip,narg,c); 332 print_number(ip,narg,c); 333 (void)putchar(','); 334 mountflagsname ((int)*ip); 335 ip++; 336 narg--; 337 } else if (ktr->ktr_code == SYS_unmount) { 338 print_number(ip,narg,c); 339 (void)putchar(','); 340 mountflagsname ((int)*ip); 341 ip++; 342 narg--; 343 } else if (ktr->ktr_code == SYS_recvmsg || 344 ktr->ktr_code == SYS_sendmsg) { 345 print_number(ip,narg,c); 346 print_number(ip,narg,c); 347 (void)putchar(','); 348 sendrecvflagsname ((int)*ip); 349 ip++; 350 narg--; 351 } else if (ktr->ktr_code == SYS_recvfrom || 352 ktr->ktr_code == SYS_sendto) { 353 print_number(ip,narg,c); 354 print_number(ip,narg,c); 355 print_number(ip,narg,c); 356 (void)putchar(','); 357 sendrecvflagsname ((int)*ip); 358 ip++; 359 narg--; 360 } else if (ktr->ktr_code == SYS_chflags || 361 ktr->ktr_code == SYS_fchflags) { 362 print_number(ip,narg,c); 363 (void)putchar(','); 364 modename((int)*ip); 365 ip++; 366 narg--; 367 } else if (ktr->ktr_code == SYS_kill) { 368 print_number(ip,narg,c); 369 (void)putchar(','); 370 signame((int)*ip); 371 ip++; 372 narg--; 373 } else if (ktr->ktr_code == SYS_reboot) { 374 (void)putchar('('); 375 rebootoptname((int)*ip); 376 ip++; 377 narg--; 378 } else if (ktr->ktr_code == SYS_umask) { 379 (void)putchar('('); 380 modename((int)*ip); 381 ip++; 382 narg--; 383 } else if (ktr->ktr_code == SYS_msync) { 384 print_number(ip,narg,c); 385 print_number(ip,narg,c); 386 (void)putchar(','); 387 msyncflagsname((int)*ip); 388 ip++; 389 narg--; 390 } else if (ktr->ktr_code == SYS_mmap) { 391 print_number(ip,narg,c); 392 print_number(ip,narg,c); 393 (void)putchar(','); 394 mmapprotname ((int)*ip); 395 (void)putchar(','); 396 ip++; 397 narg--; 398 mmapflagsname ((int)*ip); 399 ip++; 400 narg--; 401 } else if (ktr->ktr_code == SYS_mprotect) { 402 print_number(ip,narg,c); 403 print_number(ip,narg,c); 404 (void)putchar(','); 405 mmapprotname ((int)*ip); 406 ip++; 407 narg--; 408 } else if (ktr->ktr_code == SYS_madvise) { 409 print_number(ip,narg,c); 410 print_number(ip,narg,c); 411 (void)putchar(','); 412 madvisebehavname((int)*ip); 413 ip++; 414 narg--; 415 } else if (ktr->ktr_code == SYS_setpriority) { 416 (void)putchar('('); 417 prioname((int)*ip); 418 ip++; 419 narg--; 420 c = ','; 421 print_number(ip,narg,c); 422 print_number(ip,narg,c); 423 } else if (ktr->ktr_code == SYS_fcntl) { 424 int cmd; 425 int arg; 426 print_number(ip,narg,c); 427 cmd = *ip; 428 arg = *++ip; 429 (void)putchar(','); 430 fcntlcmdname(cmd, arg, decimal); 431 ip++; 432 narg-=2; 433 } else if (ktr->ktr_code == SYS_socket) { 434 (void)putchar('('); 435 sockdomainname((int)*ip); 436 ip++; 437 narg--; 438 (void)putchar(','); 439 socktypename((int)*ip); 440 ip++; 441 narg--; 442 c = ','; 443 } else if (ktr->ktr_code == SYS_setsockopt || 444 ktr->ktr_code == SYS_getsockopt) { 445 print_number(ip,narg,c); 446 (void)putchar(','); 447 sockoptlevelname((int)*ip, decimal); 448 ip++; 449 narg--; 450 (void)putchar(','); 451 sockoptname((int)*ip); 452 ip++; 453 narg--; 454 } else if (ktr->ktr_code == SYS_lseek) { 455 print_number(ip,narg,c); 456 /* Hidden 'pad' argument, not in lseek(2) */ 457 print_number(ip,narg,c); 458 print_number(ip,narg,c); 459 (void)putchar(','); 460 whencename ((int)*ip); 461 ip++; 462 narg--; 463 } else if (ktr->ktr_code == SYS_flock) { 464 print_number(ip,narg,c); 465 (void)putchar(','); 466 flockname((int)*ip); 467 ip++; 468 narg--; 469 } else if (ktr->ktr_code == SYS_mkfifo || 470 ktr->ktr_code == SYS_mkdir) { 471 print_number(ip,narg,c); 472 (void)putchar(','); 473 modename((int)*ip); 474 ip++; 475 narg--; 476 } else if (ktr->ktr_code == SYS_shutdown) { 477 print_number(ip,narg,c); 478 (void)putchar(','); 479 shutdownhowname((int)*ip); 480 ip++; 481 narg--; 482 } else if (ktr->ktr_code == SYS_socketpair) { 483 (void)putchar('('); 484 sockdomainname((int)*ip); 485 ip++; 486 narg--; 487 (void)putchar(','); 488 socktypename((int)*ip); 489 ip++; 490 narg--; 491 c = ','; 492 } else if (ktr->ktr_code == SYS_getrlimit || 493 ktr->ktr_code == SYS_setrlimit) { 494 (void)putchar('('); 495 rlimitname((int)*ip); 496 ip++; 497 narg--; 498 c = ','; 499 } else if (ktr->ktr_code == SYS_quotactl) { 500 print_number(ip,narg,c); 501 quotactlname((int)*ip); 502 ip++; 503 narg--; 504 c = ','; 505 } else if (ktr->ktr_code == SYS_rtprio) { 506 (void)putchar('('); 507 rtprioname((int)*ip); 508 ip++; 509 narg--; 510 c = ','; 511 } else if (ktr->ktr_code == SYS___semctl) { 512 print_number(ip,narg,c); 513 print_number(ip,narg,c); 514 semctlname((int)*ip); 515 ip++; 516 narg--; 517 } else if (ktr->ktr_code == SYS_semget) { 518 print_number(ip,narg,c); 519 print_number(ip,narg,c); 520 semgetname((int)*ip); 521 ip++; 522 narg--; 523 } else if (ktr->ktr_code == SYS_msgctl) { 524 print_number(ip,narg,c); 525 shmctlname((int)*ip); 526 ip++; 527 narg--; 528 } else if (ktr->ktr_code == SYS_shmat) { 529 print_number(ip,narg,c); 530 print_number(ip,narg,c); 531 shmatname((int)*ip); 532 ip++; 533 narg--; 534 } else if (ktr->ktr_code == SYS_shmctl) { 535 print_number(ip,narg,c); 536 shmctlname((int)*ip); 537 ip++; 538 narg--; 539 } else if (ktr->ktr_code == SYS_minherit) { 540 print_number(ip,narg,c); 541 print_number(ip,narg,c); 542 minheritname((int)*ip); 543 ip++; 544 narg--; 545 } else if (ktr->ktr_code == SYS_rfork) { 546 (void)putchar('('); 547 rforkname((int)*ip); 548 ip++; 549 narg--; 550 c = ','; 551 } else if (ktr->ktr_code == SYS_lio_listio) { 552 (void)putchar('('); 553 lio_listioname((int)*ip); 554 ip++; 555 narg--; 556 c = ','; 557 } else if (ktr->ktr_code == SYS_mlockall) { 558 (void)putchar('('); 559 mlockallname((int)*ip); 560 ip++; 561 narg--; 562 } else if (ktr->ktr_code == SYS_sched_setscheduler) { 563 print_number(ip,narg,c); 564 schedpolicyname((int)*ip); 565 ip++; 566 narg--; 567 } else if (ktr->ktr_code == SYS_sched_get_priority_max || 568 ktr->ktr_code == SYS_sched_get_priority_min) { 569 (void)putchar('('); 570 schedpolicyname((int)*ip); 571 ip++; 572 narg--; 573 } else if (ktr->ktr_code == SYS_sendfile) { 574 print_number(ip,narg,c); 575 print_number(ip,narg,c); 576 print_number(ip,narg,c); 577 print_number(ip,narg,c); 578 print_number(ip,narg,c); 579 print_number(ip,narg,c); 580 sendfileflagsname((int)*ip); 581 ip++; 582 narg--; 583 } else if (ktr->ktr_code == SYS_kldsym) { 584 print_number(ip,narg,c); 585 kldsymcmdname((int)*ip); 586 ip++; 587 narg--; 588 } else if (ktr->ktr_code == SYS_sigprocmask) { 589 (void)putchar('('); 590 sigprocmaskhowname((int)*ip); 591 ip++; 592 narg--; 593 c = ','; 594 } else if (ktr->ktr_code == SYS___acl_get_file || 595 ktr->ktr_code == SYS___acl_set_file || 596 ktr->ktr_code == SYS___acl_get_fd || 597 ktr->ktr_code == SYS___acl_set_fd || 598 ktr->ktr_code == SYS___acl_delete_file || 599 ktr->ktr_code == SYS___acl_delete_fd || 600 ktr->ktr_code == SYS___acl_aclcheck_file || 601 ktr->ktr_code == SYS___acl_aclcheck_fd) { 602 print_number(ip,narg,c); 603 acltypename((int)*ip); 604 ip++; 605 narg--; 606 } else if (ktr->ktr_code == SYS_sigaction) { 607 (void)putchar('('); 608 signame((int)*ip); 609 ip++; 610 narg--; 611 c = ','; 612 } else if (ktr->ktr_code == SYS_extattrctl) { 613 print_number(ip,narg,c); 614 extattrctlname((int)*ip); 615 ip++; 616 narg--; 617 } else if (ktr->ktr_code == SYS_ptrace) { 618 if (*ip < sizeof(ptrace_ops) / 619 sizeof(ptrace_ops[0]) && *ip >= 0) 620 (void)printf("(%s", ptrace_ops[*ip]); 621 #ifdef PT_GETREGS 622 else if (*ip == PT_GETREGS) 623 (void)printf("(%s", "PT_GETREGS"); 624 #endif 625 #ifdef PT_SETREGS 626 else if (*ip == PT_SETREGS) 627 (void)printf("(%s", "PT_SETREGS"); 628 #endif 629 #ifdef PT_GETFPREGS 630 else if (*ip == PT_GETFPREGS) 631 (void)printf("(%s", "PT_GETFPREGS"); 632 #endif 633 #ifdef PT_SETFPREGS 634 else if (*ip == PT_SETFPREGS) 635 (void)printf("(%s", "PT_SETFPREGS"); 636 #endif 637 #ifdef PT_GETDBREGS 638 else if (*ip == PT_GETDBREGS) 639 (void)printf("(%s", "PT_GETDBREGS"); 640 #endif 641 #ifdef PT_SETDBREGS 642 else if (*ip == PT_SETDBREGS) 643 (void)printf("(%s", "PT_SETDBREGS"); 644 #endif 645 else 646 (void)printf("(%ld", (long)*ip); 647 c = ','; 648 ip++; 649 narg--; 650 } 651 } 652 while (narg > 0) { 653 print_number(ip,narg,c); 654 } 655 (void)putchar(')'); 656 } 657 (void)putchar('\n'); 658 } 659 660 ktrsysret(struct ktr_sysret *ktr) 661 { 662 register_t ret = ktr->ktr_retval; 663 int error = ktr->ktr_error; 664 int code = ktr->ktr_code; 665 666 if (code >= nsyscalls || code < 0) 667 (void)printf("[%d] ", code); 668 else 669 (void)printf("%s ", syscallnames[code]); 670 671 if (error == 0) { 672 if (fancy) { 673 (void)printf("%d", ret); 674 if (ret < 0 || ret > 9) 675 (void)printf("/%#lx", (long)ret); 676 } else { 677 if (decimal) 678 (void)printf("%ld", (long)ret); 679 else 680 (void)printf("%#lx", (long)ret); 681 } 682 } else if (error == ERESTART) 683 (void)printf("RESTART"); 684 else if (error == EJUSTRETURN) 685 (void)printf("JUSTRETURN"); 686 else { 687 (void)printf("-1 errno %d", ktr->ktr_error); 688 if (fancy) 689 (void)printf(" %s", strerror(ktr->ktr_error)); 690 } 691 (void)putchar('\n'); 692 } 693 694 ktrnamei(char *cp, int len) 695 { 696 (void)printf("\"%.*s\"\n", len, cp); 697 } 698 699 ktrgenio(struct ktr_genio *ktr, int len) 700 { 701 int datalen = len - sizeof (struct ktr_genio); 702 char *dp = (char *)ktr + sizeof (struct ktr_genio); 703 char *cp; 704 int col = 0; 705 int width; 706 char visbuf[5]; 707 static screenwidth = 0; 708 709 if (screenwidth == 0) { 710 struct winsize ws; 711 712 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 713 ws.ws_col > 8) 714 screenwidth = ws.ws_col; 715 else 716 screenwidth = 80; 717 } 718 printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 719 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 720 datalen == 1 ? "" : "s"); 721 if (maxdata && datalen > maxdata) 722 datalen = maxdata; 723 (void)printf(" \""); 724 col = 8; 725 for (;datalen > 0; datalen--, dp++) { 726 (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 727 cp = visbuf; 728 /* 729 * Keep track of printables and 730 * space chars (like fold(1)). 731 */ 732 if (col == 0) { 733 (void)putchar('\t'); 734 col = 8; 735 } 736 switch(*cp) { 737 case '\n': 738 col = 0; 739 (void)putchar('\n'); 740 continue; 741 case '\t': 742 width = 8 - (col&07); 743 break; 744 default: 745 width = strlen(cp); 746 } 747 if (col + width > (screenwidth-2)) { 748 (void)printf("\\\n\t"); 749 col = 8; 750 } 751 col += width; 752 do { 753 (void)putchar(*cp++); 754 } while (*cp); 755 } 756 if (col == 0) 757 (void)printf(" "); 758 (void)printf("\"\n"); 759 } 760 761 char *signames[NSIG] = { 762 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 763 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 764 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 765 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 766 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 767 "USR2", NULL, /* 31 - 32 */ 768 }; 769 770 ktrpsig(struct ktr_psig *psig) 771 { 772 (void)printf("SIG%s ", signames[psig->signo]); 773 if (psig->action == SIG_DFL) 774 (void)printf("SIG_DFL\n"); 775 else 776 (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 777 (u_long)psig->action, psig->mask, psig->code); 778 } 779 780 ktrcsw(struct ktr_csw *cs) 781 { 782 (void)printf("%s %s\n", cs->out ? "stop" : "resume", 783 cs->user ? "user" : "kernel"); 784 } 785 786 struct utrace_malloc { 787 void *p; 788 size_t s; 789 void *r; 790 }; 791 792 void 793 ktruser_malloc(int len, unsigned char *p) 794 { 795 struct utrace_malloc *ut = (struct utrace_malloc *)p; 796 797 if (ut->p == NULL) { 798 if (ut->s == 0 && ut->r == NULL) 799 printf("malloc_init()\n"); 800 else 801 printf("%p = malloc(%zu)\n", ut->r, ut->s); 802 } else { 803 if (ut->s == 0) 804 printf("free(%p)\n", ut->p); 805 else 806 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); 807 } 808 } 809 810 ktruser(int len, unsigned char *p) 811 { 812 if (len == sizeof(struct utrace_malloc)) { 813 ktruser_malloc(len, p); 814 return; 815 } 816 817 (void)printf("%d ", len); 818 while (len--) 819 (void)printf(" %02x", *p++); 820 (void)printf("\n"); 821 } 822 823 usage(void) 824 { 825 (void)fprintf(stderr, 826 "usage: kdump [-dnlRT] [-f trfile] [-m maxdata] [-t [cnisuw]] [-p pid]\n"); 827 exit(1); 828 } 829 830 timevalsub(struct timeval *t1, struct timeval *t2) 831 { 832 t1->tv_sec -= t2->tv_sec; 833 t1->tv_usec -= t2->tv_usec; 834 timevalfix(t1); 835 } 836 837 timevalfix(struct timeval *t1) 838 { 839 if (t1->tv_usec < 0) { 840 t1->tv_sec--; 841 t1->tv_usec += 1000000; 842 } 843 if (t1->tv_usec >= 1000000) { 844 t1->tv_sec++; 845 t1->tv_usec -= 1000000; 846 } 847 } 848