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 print_number(ip,narg,c); 417 print_number(ip,narg,c); 418 (void)putchar(','); 419 prioname((int)*ip); 420 ip++; 421 narg--; 422 } else if (ktr->ktr_code == SYS_fcntl) { 423 int cmd; 424 int arg; 425 print_number(ip,narg,c); 426 cmd = *ip; 427 arg = *++ip; 428 (void)putchar(','); 429 fcntlcmdname(cmd, arg, decimal); 430 ip++; 431 narg-=2; 432 } else if (ktr->ktr_code == SYS_socket) { 433 (void)putchar('('); 434 sockdomainname((int)*ip); 435 ip++; 436 narg--; 437 (void)putchar(','); 438 socktypename((int)*ip); 439 ip++; 440 narg--; 441 c = ','; 442 } else if (ktr->ktr_code == SYS_setsockopt || 443 ktr->ktr_code == SYS_getsockopt) { 444 print_number(ip,narg,c); 445 (void)putchar(','); 446 sockoptlevelname((int)*ip, decimal); 447 ip++; 448 narg--; 449 (void)putchar(','); 450 sockoptname((int)*ip); 451 ip++; 452 narg--; 453 } else if (ktr->ktr_code == SYS_lseek) { 454 print_number(ip,narg,c); 455 /* Hidden 'pad' argument, not in lseek(2) */ 456 print_number(ip,narg,c); 457 print_number(ip,narg,c); 458 (void)putchar(','); 459 whencename ((int)*ip); 460 ip++; 461 narg--; 462 } else if (ktr->ktr_code == SYS_flock) { 463 print_number(ip,narg,c); 464 (void)putchar(','); 465 flockname((int)*ip); 466 ip++; 467 narg--; 468 } else if (ktr->ktr_code == SYS_mkfifo || 469 ktr->ktr_code == SYS_mkdir) { 470 print_number(ip,narg,c); 471 (void)putchar(','); 472 modename((int)*ip); 473 ip++; 474 narg--; 475 } else if (ktr->ktr_code == SYS_shutdown) { 476 print_number(ip,narg,c); 477 (void)putchar(','); 478 shutdownhowname((int)*ip); 479 ip++; 480 narg--; 481 } else if (ktr->ktr_code == SYS_socketpair) { 482 (void)putchar('('); 483 sockdomainname((int)*ip); 484 ip++; 485 narg--; 486 (void)putchar(','); 487 socktypename((int)*ip); 488 ip++; 489 narg--; 490 c = ','; 491 } else if (ktr->ktr_code == SYS_getrlimit || 492 ktr->ktr_code == SYS_setrlimit) { 493 (void)putchar('('); 494 rlimitname((int)*ip); 495 ip++; 496 narg--; 497 c = ','; 498 } else if (ktr->ktr_code == SYS_quotactl) { 499 print_number(ip,narg,c); 500 quotactlname((int)*ip); 501 ip++; 502 narg--; 503 c = ','; 504 } else if (ktr->ktr_code == SYS_rtprio) { 505 (void)putchar('('); 506 rtprioname((int)*ip); 507 ip++; 508 narg--; 509 c = ','; 510 } else if (ktr->ktr_code == SYS___semctl) { 511 print_number(ip,narg,c); 512 print_number(ip,narg,c); 513 semctlname((int)*ip); 514 ip++; 515 narg--; 516 } else if (ktr->ktr_code == SYS_semget) { 517 print_number(ip,narg,c); 518 print_number(ip,narg,c); 519 semgetname((int)*ip); 520 ip++; 521 narg--; 522 } else if (ktr->ktr_code == SYS_msgctl) { 523 print_number(ip,narg,c); 524 shmctlname((int)*ip); 525 ip++; 526 narg--; 527 } else if (ktr->ktr_code == SYS_shmat) { 528 print_number(ip,narg,c); 529 print_number(ip,narg,c); 530 shmatname((int)*ip); 531 ip++; 532 narg--; 533 } else if (ktr->ktr_code == SYS_shmctl) { 534 print_number(ip,narg,c); 535 shmctlname((int)*ip); 536 ip++; 537 narg--; 538 } else if (ktr->ktr_code == SYS_minherit) { 539 print_number(ip,narg,c); 540 print_number(ip,narg,c); 541 minheritname((int)*ip); 542 ip++; 543 narg--; 544 } else if (ktr->ktr_code == SYS_rfork) { 545 (void)putchar('('); 546 rforkname((int)*ip); 547 ip++; 548 narg--; 549 c = ','; 550 } else if (ktr->ktr_code == SYS_lio_listio) { 551 (void)putchar('('); 552 lio_listioname((int)*ip); 553 ip++; 554 narg--; 555 c = ','; 556 } else if (ktr->ktr_code == SYS_mlockall) { 557 (void)putchar('('); 558 mlockallname((int)*ip); 559 ip++; 560 narg--; 561 } else if (ktr->ktr_code == SYS_sched_setscheduler) { 562 print_number(ip,narg,c); 563 schedpolicyname((int)*ip); 564 ip++; 565 narg--; 566 } else if (ktr->ktr_code == SYS_sched_get_priority_max || 567 ktr->ktr_code == SYS_sched_get_priority_min) { 568 (void)putchar('('); 569 schedpolicyname((int)*ip); 570 ip++; 571 narg--; 572 } else if (ktr->ktr_code == SYS_sendfile) { 573 print_number(ip,narg,c); 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 sendfileflagsname((int)*ip); 580 ip++; 581 narg--; 582 } else if (ktr->ktr_code == SYS_kldsym) { 583 print_number(ip,narg,c); 584 kldsymcmdname((int)*ip); 585 ip++; 586 narg--; 587 } else if (ktr->ktr_code == SYS_sigprocmask) { 588 (void)putchar('('); 589 sigprocmaskhowname((int)*ip); 590 ip++; 591 narg--; 592 c = ','; 593 } else if (ktr->ktr_code == SYS___acl_get_file || 594 ktr->ktr_code == SYS___acl_set_file || 595 ktr->ktr_code == SYS___acl_get_fd || 596 ktr->ktr_code == SYS___acl_set_fd || 597 ktr->ktr_code == SYS___acl_delete_file || 598 ktr->ktr_code == SYS___acl_delete_fd || 599 ktr->ktr_code == SYS___acl_aclcheck_file || 600 ktr->ktr_code == SYS___acl_aclcheck_fd) { 601 print_number(ip,narg,c); 602 acltypename((int)*ip); 603 ip++; 604 narg--; 605 } else if (ktr->ktr_code == SYS_sigaction) { 606 (void)putchar('('); 607 signame((int)*ip); 608 ip++; 609 narg--; 610 c = ','; 611 } else if (ktr->ktr_code == SYS_extattrctl) { 612 print_number(ip,narg,c); 613 extattrctlname((int)*ip); 614 ip++; 615 narg--; 616 } else if (ktr->ktr_code == SYS_ptrace) { 617 if (*ip < sizeof(ptrace_ops) / 618 sizeof(ptrace_ops[0]) && *ip >= 0) 619 (void)printf("(%s", ptrace_ops[*ip]); 620 #ifdef PT_GETREGS 621 else if (*ip == PT_GETREGS) 622 (void)printf("(%s", "PT_GETREGS"); 623 #endif 624 #ifdef PT_SETREGS 625 else if (*ip == PT_SETREGS) 626 (void)printf("(%s", "PT_SETREGS"); 627 #endif 628 #ifdef PT_GETFPREGS 629 else if (*ip == PT_GETFPREGS) 630 (void)printf("(%s", "PT_GETFPREGS"); 631 #endif 632 #ifdef PT_SETFPREGS 633 else if (*ip == PT_SETFPREGS) 634 (void)printf("(%s", "PT_SETFPREGS"); 635 #endif 636 #ifdef PT_GETDBREGS 637 else if (*ip == PT_GETDBREGS) 638 (void)printf("(%s", "PT_GETDBREGS"); 639 #endif 640 #ifdef PT_SETDBREGS 641 else if (*ip == PT_SETDBREGS) 642 (void)printf("(%s", "PT_SETDBREGS"); 643 #endif 644 else 645 (void)printf("(%ld", (long)*ip); 646 c = ','; 647 ip++; 648 narg--; 649 } 650 } 651 while (narg > 0) { 652 print_number(ip,narg,c); 653 } 654 (void)putchar(')'); 655 } 656 (void)putchar('\n'); 657 } 658 659 ktrsysret(struct ktr_sysret *ktr) 660 { 661 register_t ret = ktr->ktr_retval; 662 int error = ktr->ktr_error; 663 int code = ktr->ktr_code; 664 665 if (code >= nsyscalls || code < 0) 666 (void)printf("[%d] ", code); 667 else 668 (void)printf("%s ", syscallnames[code]); 669 670 if (error == 0) { 671 if (fancy) { 672 (void)printf("%d", ret); 673 if (ret < 0 || ret > 9) 674 (void)printf("/%#lx", (long)ret); 675 } else { 676 if (decimal) 677 (void)printf("%ld", (long)ret); 678 else 679 (void)printf("%#lx", (long)ret); 680 } 681 } else if (error == ERESTART) 682 (void)printf("RESTART"); 683 else if (error == EJUSTRETURN) 684 (void)printf("JUSTRETURN"); 685 else { 686 (void)printf("-1 errno %d", ktr->ktr_error); 687 if (fancy) 688 (void)printf(" %s", strerror(ktr->ktr_error)); 689 } 690 (void)putchar('\n'); 691 } 692 693 ktrnamei(char *cp, int len) 694 { 695 (void)printf("\"%.*s\"\n", len, cp); 696 } 697 698 ktrgenio(struct ktr_genio *ktr, int len) 699 { 700 int datalen = len - sizeof (struct ktr_genio); 701 char *dp = (char *)ktr + sizeof (struct ktr_genio); 702 char *cp; 703 int col = 0; 704 int width; 705 char visbuf[5]; 706 static screenwidth = 0; 707 708 if (screenwidth == 0) { 709 struct winsize ws; 710 711 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 712 ws.ws_col > 8) 713 screenwidth = ws.ws_col; 714 else 715 screenwidth = 80; 716 } 717 printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 718 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 719 datalen == 1 ? "" : "s"); 720 if (maxdata && datalen > maxdata) 721 datalen = maxdata; 722 (void)printf(" \""); 723 col = 8; 724 for (;datalen > 0; datalen--, dp++) { 725 (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 726 cp = visbuf; 727 /* 728 * Keep track of printables and 729 * space chars (like fold(1)). 730 */ 731 if (col == 0) { 732 (void)putchar('\t'); 733 col = 8; 734 } 735 switch(*cp) { 736 case '\n': 737 col = 0; 738 (void)putchar('\n'); 739 continue; 740 case '\t': 741 width = 8 - (col&07); 742 break; 743 default: 744 width = strlen(cp); 745 } 746 if (col + width > (screenwidth-2)) { 747 (void)printf("\\\n\t"); 748 col = 8; 749 } 750 col += width; 751 do { 752 (void)putchar(*cp++); 753 } while (*cp); 754 } 755 if (col == 0) 756 (void)printf(" "); 757 (void)printf("\"\n"); 758 } 759 760 char *signames[NSIG] = { 761 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 762 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 763 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 764 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 765 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 766 "USR2", NULL, /* 31 - 32 */ 767 }; 768 769 ktrpsig(struct ktr_psig *psig) 770 { 771 (void)printf("SIG%s ", signames[psig->signo]); 772 if (psig->action == SIG_DFL) 773 (void)printf("SIG_DFL\n"); 774 else 775 (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 776 (u_long)psig->action, psig->mask, psig->code); 777 } 778 779 ktrcsw(struct ktr_csw *cs) 780 { 781 (void)printf("%s %s\n", cs->out ? "stop" : "resume", 782 cs->user ? "user" : "kernel"); 783 } 784 785 struct utrace_malloc { 786 void *p; 787 size_t s; 788 void *r; 789 }; 790 791 void 792 ktruser_malloc(int len, unsigned char *p) 793 { 794 struct utrace_malloc *ut = (struct utrace_malloc *)p; 795 796 if (ut->p == NULL) { 797 if (ut->s == 0 && ut->r == NULL) 798 printf("malloc_init()\n"); 799 else 800 printf("%p = malloc(%zu)\n", ut->r, ut->s); 801 } else { 802 if (ut->s == 0) 803 printf("free(%p)\n", ut->p); 804 else 805 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); 806 } 807 } 808 809 ktruser(int len, unsigned char *p) 810 { 811 if (len == sizeof(struct utrace_malloc)) { 812 ktruser_malloc(len, p); 813 return; 814 } 815 816 (void)printf("%d ", len); 817 while (len--) 818 (void)printf(" %02x", *p++); 819 (void)printf("\n"); 820 } 821 822 usage(void) 823 { 824 (void)fprintf(stderr, 825 "usage: kdump [-dnlRT] [-f trfile] [-m maxdata] [-t [cnisuw]] [-p pid]\n"); 826 exit(1); 827 } 828 829 timevalsub(struct timeval *t1, struct timeval *t2) 830 { 831 t1->tv_sec -= t2->tv_sec; 832 t1->tv_usec -= t2->tv_usec; 833 timevalfix(t1); 834 } 835 836 timevalfix(struct timeval *t1) 837 { 838 if (t1->tv_usec < 0) { 839 t1->tv_sec--; 840 t1->tv_usec += 1000000; 841 } 842 if (t1->tv_usec >= 1000000) { 843 t1->tv_sec++; 844 t1->tv_usec -= 1000000; 845 } 846 } 847