kdump.c revision 165758
11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1988, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 3527443Scharnierstatic const char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1988, 1993\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 381590Srgrimes#endif /* not lint */ 391590Srgrimes 401590Srgrimes#ifndef lint 4127443Scharnier#if 0 421590Srgrimesstatic char sccsid[] = "@(#)kdump.c 8.1 (Berkeley) 6/6/93"; 4327443Scharnier#endif 441590Srgrimes#endif /* not lint */ 4599112Sobrien#include <sys/cdefs.h> 4699112Sobrien__FBSDID("$FreeBSD: head/usr.bin/kdump/kdump.c 165758 2007-01-04 04:46:59Z rodrigc $"); 471590Srgrimes 4855206Speter#define _KERNEL 492215Scsgrextern int errno; 502215Scsgr#include <sys/errno.h> 5155206Speter#undef _KERNEL 521590Srgrimes#include <sys/param.h> 531590Srgrimes#include <sys/errno.h> 54100824Sdwmalone#define _KERNEL 551590Srgrimes#include <sys/time.h> 56100824Sdwmalone#undef _KERNEL 571590Srgrimes#include <sys/uio.h> 581590Srgrimes#include <sys/ktrace.h> 591590Srgrimes#include <sys/ioctl.h> 601590Srgrimes#include <sys/ptrace.h> 61165758Srodrigc#include <sys/socket.h> 6227443Scharnier#include <err.h> 6327443Scharnier#include <locale.h> 641590Srgrimes#include <stdio.h> 651590Srgrimes#include <stdlib.h> 661590Srgrimes#include <string.h> 6727443Scharnier#include <unistd.h> 6827443Scharnier#include <vis.h> 691590Srgrimes#include "ktrace.h" 70158766Snetchild#include "kdump_subr.h" 711590Srgrimes 72100824Sdwmaloneint fread_tail(void *, int, int); 73100824Sdwmalonevoid dumpheader(struct ktr_header *); 74100824Sdwmalonevoid ktrsyscall(struct ktr_syscall *); 75100824Sdwmalonevoid ktrsysret(struct ktr_sysret *); 76100824Sdwmalonevoid ktrnamei(char *, int); 77115759Spetervoid hexdump(char *, int, int); 78115759Spetervoid visdump(char *, int, int); 79100824Sdwmalonevoid ktrgenio(struct ktr_genio *, int); 80100824Sdwmalonevoid ktrpsig(struct ktr_psig *); 81100824Sdwmalonevoid ktrcsw(struct ktr_csw *); 82100824Sdwmalonevoid ktruser(int, unsigned char *); 83100824Sdwmalonevoid usage(void); 84135466Sruconst char *ioctlname(u_long); 85100824Sdwmalone 86152331Srwatsonint timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata; 87100824Sdwmaloneconst char *tracefile = DEF_TRACEFILE; 881590Srgrimesstruct ktr_header ktr_header; 891590Srgrimes 901590Srgrimes#define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 911590Srgrimes 92100824Sdwmaloneint 93100824Sdwmalonemain(int argc, char *argv[]) 941590Srgrimes{ 951590Srgrimes int ch, ktrlen, size; 96100824Sdwmalone void *m; 971590Srgrimes int trpoints = ALL_POINTS; 98112201Sjhb int drop_logged; 99115759Speter pid_t pid = 0; 1001590Srgrimes 10111823Sache (void) setlocale(LC_CTYPE, ""); 10211823Sache 103152331Srwatson while ((ch = getopt(argc,argv,"f:dElm:np:HRsTt:")) != -1) 1041590Srgrimes switch((char)ch) { 1051590Srgrimes case 'f': 1061590Srgrimes tracefile = optarg; 1071590Srgrimes break; 1081590Srgrimes case 'd': 1091590Srgrimes decimal = 1; 1101590Srgrimes break; 1111590Srgrimes case 'l': 1121590Srgrimes tail = 1; 1131590Srgrimes break; 1141590Srgrimes case 'm': 1151590Srgrimes maxdata = atoi(optarg); 1161590Srgrimes break; 1171590Srgrimes case 'n': 1181590Srgrimes fancy = 0; 1191590Srgrimes break; 120115759Speter case 'p': 121115759Speter pid = atoi(optarg); 122115759Speter break; 123152331Srwatson case 's': 124152331Srwatson suppressdata = 1; 125152331Srwatson break; 126123187Speter case 'E': 127123187Speter timestamp = 3; /* elapsed timestamp */ 128123187Speter break; 129151930Srwatson case 'H': 130151930Srwatson threads = 1; 131151930Srwatson break; 1321590Srgrimes case 'R': 1331590Srgrimes timestamp = 2; /* relative timestamp */ 1341590Srgrimes break; 1351590Srgrimes case 'T': 1361590Srgrimes timestamp = 1; 1371590Srgrimes break; 1381590Srgrimes case 't': 1391590Srgrimes trpoints = getpoints(optarg); 14027443Scharnier if (trpoints < 0) 14127443Scharnier errx(1, "unknown trace point in %s", optarg); 1421590Srgrimes break; 1431590Srgrimes default: 1441590Srgrimes usage(); 1451590Srgrimes } 1461590Srgrimes 14719853Sfenner if (argc > optind) 1481590Srgrimes usage(); 1491590Srgrimes 1501590Srgrimes m = (void *)malloc(size = 1025); 15127443Scharnier if (m == NULL) 15227443Scharnier errx(1, "%s", strerror(ENOMEM)); 15327443Scharnier if (!freopen(tracefile, "r", stdin)) 15427443Scharnier err(1, "%s", tracefile); 155112201Sjhb drop_logged = 0; 1561590Srgrimes while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 157112201Sjhb if (ktr_header.ktr_type & KTR_DROP) { 158112201Sjhb ktr_header.ktr_type &= ~KTR_DROP; 159151930Srwatson if (!drop_logged && threads) { 160151930Srwatson (void)printf("%6d %6d %-8.*s Events dropped.\n", 161151930Srwatson ktr_header.ktr_pid, ktr_header.ktr_tid > 162151930Srwatson 0 ? ktr_header.ktr_tid : 0, MAXCOMLEN, 163151930Srwatson ktr_header.ktr_comm); 164151930Srwatson drop_logged = 1; 165151930Srwatson } else if (!drop_logged) { 166112201Sjhb (void)printf("%6d %-8.*s Events dropped.\n", 167112201Sjhb ktr_header.ktr_pid, MAXCOMLEN, 168112201Sjhb ktr_header.ktr_comm); 169112201Sjhb drop_logged = 1; 170112201Sjhb } 171112201Sjhb } 1721590Srgrimes if (trpoints & (1<<ktr_header.ktr_type)) 173115759Speter if (pid == 0 || ktr_header.ktr_pid == pid) 174115759Speter dumpheader(&ktr_header); 17527443Scharnier if ((ktrlen = ktr_header.ktr_len) < 0) 17627443Scharnier errx(1, "bogus length 0x%x", ktrlen); 1771590Srgrimes if (ktrlen > size) { 1781590Srgrimes m = (void *)realloc(m, ktrlen+1); 17927443Scharnier if (m == NULL) 18027443Scharnier errx(1, "%s", strerror(ENOMEM)); 1811590Srgrimes size = ktrlen; 1821590Srgrimes } 18327443Scharnier if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 18427443Scharnier errx(1, "data too short"); 185115759Speter if (pid && ktr_header.ktr_pid != pid) 186115759Speter continue; 1871590Srgrimes if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 1881590Srgrimes continue; 189112201Sjhb drop_logged = 0; 1901590Srgrimes switch (ktr_header.ktr_type) { 1911590Srgrimes case KTR_SYSCALL: 1921590Srgrimes ktrsyscall((struct ktr_syscall *)m); 1931590Srgrimes break; 1941590Srgrimes case KTR_SYSRET: 1951590Srgrimes ktrsysret((struct ktr_sysret *)m); 1961590Srgrimes break; 1971590Srgrimes case KTR_NAMEI: 1981590Srgrimes ktrnamei(m, ktrlen); 1991590Srgrimes break; 2001590Srgrimes case KTR_GENIO: 2011590Srgrimes ktrgenio((struct ktr_genio *)m, ktrlen); 2021590Srgrimes break; 2031590Srgrimes case KTR_PSIG: 2041590Srgrimes ktrpsig((struct ktr_psig *)m); 2051590Srgrimes break; 2061590Srgrimes case KTR_CSW: 2071590Srgrimes ktrcsw((struct ktr_csw *)m); 2081590Srgrimes break; 20918400Sphk case KTR_USER: 21018470Sphk ktruser(ktrlen, m); 21118400Sphk break; 212112203Sjhb default: 213112203Sjhb printf("\n"); 214112203Sjhb break; 2151590Srgrimes } 2161590Srgrimes if (tail) 2171590Srgrimes (void)fflush(stdout); 2181590Srgrimes } 219100824Sdwmalone return 0; 2201590Srgrimes} 2211590Srgrimes 222100824Sdwmaloneint 223100824Sdwmalonefread_tail(void *buf, int size, int num) 2241590Srgrimes{ 2251590Srgrimes int i; 2261590Srgrimes 2271590Srgrimes while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 2281590Srgrimes (void)sleep(1); 2291590Srgrimes clearerr(stdin); 2301590Srgrimes } 2311590Srgrimes return (i); 2321590Srgrimes} 2331590Srgrimes 234100824Sdwmalonevoid 235100824Sdwmalonedumpheader(struct ktr_header *kth) 2361590Srgrimes{ 2371590Srgrimes static char unknown[64]; 2381590Srgrimes static struct timeval prevtime, temp; 239100824Sdwmalone const char *type; 2401590Srgrimes 2411590Srgrimes switch (kth->ktr_type) { 2421590Srgrimes case KTR_SYSCALL: 2431590Srgrimes type = "CALL"; 2441590Srgrimes break; 2451590Srgrimes case KTR_SYSRET: 2461590Srgrimes type = "RET "; 2471590Srgrimes break; 2481590Srgrimes case KTR_NAMEI: 2491590Srgrimes type = "NAMI"; 2501590Srgrimes break; 2511590Srgrimes case KTR_GENIO: 2521590Srgrimes type = "GIO "; 2531590Srgrimes break; 2541590Srgrimes case KTR_PSIG: 2551590Srgrimes type = "PSIG"; 2561590Srgrimes break; 2571590Srgrimes case KTR_CSW: 2581590Srgrimes type = "CSW"; 2591590Srgrimes break; 26018400Sphk case KTR_USER: 26118400Sphk type = "USER"; 26218400Sphk break; 2631590Srgrimes default: 2641590Srgrimes (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 2651590Srgrimes type = unknown; 2661590Srgrimes } 2671590Srgrimes 268151930Srwatson /* 269151930Srwatson * The ktr_tid field was previously the ktr_buffer field, which held 270151930Srwatson * the kernel pointer value for the buffer associated with data 271151930Srwatson * following the record header. It now holds a threadid, but only 272151930Srwatson * for trace files after the change. Older trace files still contain 273151930Srwatson * kernel pointers. Detect this and suppress the results by printing 274151930Srwatson * negative tid's as 0. 275151930Srwatson */ 276151930Srwatson if (threads) 277151930Srwatson (void)printf("%6d %6d %-8.*s ", kth->ktr_pid, kth->ktr_tid > 278151930Srwatson 0 ? kth->ktr_tid : 0, MAXCOMLEN, kth->ktr_comm); 279151930Srwatson else 280151930Srwatson (void)printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN, 281151930Srwatson kth->ktr_comm); 2821590Srgrimes if (timestamp) { 283123187Speter if (timestamp == 3) { 284123187Speter if (prevtime.tv_sec == 0) 285123187Speter prevtime = kth->ktr_time; 286123187Speter timevalsub(&kth->ktr_time, &prevtime); 287123187Speter } 2881590Srgrimes if (timestamp == 2) { 2891590Srgrimes temp = kth->ktr_time; 2901590Srgrimes timevalsub(&kth->ktr_time, &prevtime); 2911590Srgrimes prevtime = temp; 2921590Srgrimes } 2931590Srgrimes (void)printf("%ld.%06ld ", 2941590Srgrimes kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); 2951590Srgrimes } 2961590Srgrimes (void)printf("%s ", type); 2971590Srgrimes} 2981590Srgrimes 2991590Srgrimes#include <sys/syscall.h> 3001590Srgrimes#define KTRACE 3014721Sphk#include <sys/kern/syscalls.c> 3021590Srgrimes#undef KTRACE 3031590Srgrimesint nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 3041590Srgrimes 305100824Sdwmalonestatic const char *ptrace_ops[] = { 3061590Srgrimes "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U", 3071590Srgrimes "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE", 30848234Sbde "PT_KILL", "PT_STEP", "PT_ATTACH", "PT_DETACH", 3091590Srgrimes}; 3101590Srgrimes 311100824Sdwmalonevoid 312100824Sdwmalonektrsyscall(struct ktr_syscall *ktr) 3131590Srgrimes{ 314100824Sdwmalone int narg = ktr->ktr_narg; 315100824Sdwmalone register_t *ip; 3161590Srgrimes 3171590Srgrimes if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) 3181590Srgrimes (void)printf("[%d]", ktr->ktr_code); 3191590Srgrimes else 3201590Srgrimes (void)printf("%s", syscallnames[ktr->ktr_code]); 32147957Sdt ip = &ktr->ktr_args[0]; 3221590Srgrimes if (narg) { 3231590Srgrimes char c = '('; 3241590Srgrimes if (fancy) { 325158766Snetchild 326158766Snetchild#define print_number(i,n,c) do { \ 327158766Snetchild if (decimal) \ 328158766Snetchild (void)printf("%c%ld", c, (long)*i); \ 329158766Snetchild else \ 330158766Snetchild (void)printf("%c%#lx", c, (long)*i); \ 331158766Snetchild i++; \ 332158766Snetchild n--; \ 333158766Snetchild c = ','; \ 334158766Snetchild } while (0); 335158766Snetchild 3361590Srgrimes if (ktr->ktr_code == SYS_ioctl) { 337100824Sdwmalone const char *cp; 338158766Snetchild print_number(ip,narg,c); 3391590Srgrimes if ((cp = ioctlname(*ip)) != NULL) 3401590Srgrimes (void)printf(",%s", cp); 3411590Srgrimes else { 3421590Srgrimes if (decimal) 34347957Sdt (void)printf(",%ld", (long)*ip); 3441590Srgrimes else 34547957Sdt (void)printf(",%#lx ", (long)*ip); 3461590Srgrimes } 3471590Srgrimes c = ','; 3481590Srgrimes ip++; 3491590Srgrimes narg--; 3501590Srgrimes } else if (ktr->ktr_code == SYS_ptrace) { 351100824Sdwmalone if ((size_t)*ip < sizeof(ptrace_ops) / 35248234Sbde sizeof(ptrace_ops[0]) && *ip >= 0) 3531590Srgrimes (void)printf("(%s", ptrace_ops[*ip]); 35448234Sbde#ifdef PT_GETREGS 35548234Sbde else if (*ip == PT_GETREGS) 35648234Sbde (void)printf("(%s", "PT_GETREGS"); 35748234Sbde#endif 35848234Sbde#ifdef PT_SETREGS 35948234Sbde else if (*ip == PT_SETREGS) 36048234Sbde (void)printf("(%s", "PT_SETREGS"); 36148234Sbde#endif 36248234Sbde#ifdef PT_GETFPREGS 36348234Sbde else if (*ip == PT_GETFPREGS) 36448234Sbde (void)printf("(%s", "PT_GETFPREGS"); 36548234Sbde#endif 36648234Sbde#ifdef PT_SETFPREGS 36748234Sbde else if (*ip == PT_SETFPREGS) 36848234Sbde (void)printf("(%s", "PT_SETFPREGS"); 36948234Sbde#endif 37048852Sbde#ifdef PT_GETDBREGS 37148852Sbde else if (*ip == PT_GETDBREGS) 37248852Sbde (void)printf("(%s", "PT_GETDBREGS"); 37348852Sbde#endif 37448852Sbde#ifdef PT_SETDBREGS 37548852Sbde else if (*ip == PT_SETDBREGS) 37648852Sbde (void)printf("(%s", "PT_SETDBREGS"); 37748852Sbde#endif 3781590Srgrimes else 37947957Sdt (void)printf("(%ld", (long)*ip); 3801590Srgrimes c = ','; 3811590Srgrimes ip++; 3821590Srgrimes narg--; 383158766Snetchild } else if (ktr->ktr_code == SYS_access || 384158766Snetchild ktr->ktr_code == SYS_eaccess) { 385158766Snetchild print_number(ip,narg,c); 386158766Snetchild (void)putchar(','); 387158766Snetchild accessmodename ((int)*ip); 388158766Snetchild ip++; 389158766Snetchild narg--; 390158766Snetchild } else if (ktr->ktr_code == SYS_open) { 391158766Snetchild int flags; 392158766Snetchild int mode; 393158766Snetchild print_number(ip,narg,c); 394158766Snetchild flags = *ip; 395158766Snetchild mode = *++ip; 396158766Snetchild (void)putchar(','); 397158766Snetchild flagsandmodename (flags, mode, decimal); 398158766Snetchild ip++; 399158766Snetchild narg-=2; 400158766Snetchild } else if (ktr->ktr_code == SYS_wait4) { 401158766Snetchild print_number(ip,narg,c); 402158766Snetchild print_number(ip,narg,c); 403158766Snetchild (void)putchar(','); 404158766Snetchild wait4optname ((int)*ip); 405158766Snetchild ip++; 406158766Snetchild narg--; 407158766Snetchild } else if (ktr->ktr_code == SYS_chmod || 408158766Snetchild ktr->ktr_code == SYS_fchmod || 409158766Snetchild ktr->ktr_code == SYS_lchmod) { 410158766Snetchild print_number(ip,narg,c); 411158766Snetchild (void)putchar(','); 412158766Snetchild modename ((int)*ip); 413158766Snetchild ip++; 414158766Snetchild narg--; 415158766Snetchild } else if (ktr->ktr_code == SYS_mknod) { 416158766Snetchild print_number(ip,narg,c); 417158766Snetchild (void)putchar(','); 418158766Snetchild modename ((int)*ip); 419158766Snetchild ip++; 420158766Snetchild narg--; 421158766Snetchild } else if (ktr->ktr_code == SYS_getfsstat) { 422158766Snetchild print_number(ip,narg,c); 423158766Snetchild print_number(ip,narg,c); 424158766Snetchild (void)putchar(','); 425158766Snetchild getfsstatflagsname ((int)*ip); 426158766Snetchild ip++; 427158766Snetchild narg--; 428158766Snetchild } else if (ktr->ktr_code == SYS_mount) { 429158766Snetchild print_number(ip,narg,c); 430158766Snetchild print_number(ip,narg,c); 431158766Snetchild (void)putchar(','); 432158766Snetchild mountflagsname ((int)*ip); 433158766Snetchild ip++; 434158766Snetchild narg--; 435158766Snetchild } else if (ktr->ktr_code == SYS_unmount) { 436158766Snetchild print_number(ip,narg,c); 437158766Snetchild (void)putchar(','); 438158766Snetchild mountflagsname ((int)*ip); 439158766Snetchild ip++; 440158766Snetchild narg--; 441158766Snetchild } else if (ktr->ktr_code == SYS_recvmsg || 442158766Snetchild ktr->ktr_code == SYS_sendmsg) { 443158766Snetchild print_number(ip,narg,c); 444158766Snetchild print_number(ip,narg,c); 445158766Snetchild (void)putchar(','); 446158766Snetchild sendrecvflagsname ((int)*ip); 447158766Snetchild ip++; 448158766Snetchild narg--; 449158766Snetchild } else if (ktr->ktr_code == SYS_recvfrom || 450158766Snetchild ktr->ktr_code == SYS_sendto) { 451158766Snetchild print_number(ip,narg,c); 452158766Snetchild print_number(ip,narg,c); 453158766Snetchild print_number(ip,narg,c); 454158766Snetchild (void)putchar(','); 455158766Snetchild sendrecvflagsname ((int)*ip); 456158766Snetchild ip++; 457158766Snetchild narg--; 458158766Snetchild } else if (ktr->ktr_code == SYS_chflags || 459158766Snetchild ktr->ktr_code == SYS_fchflags || 460158766Snetchild ktr->ktr_code == SYS_lchflags) { 461158766Snetchild print_number(ip,narg,c); 462158766Snetchild (void)putchar(','); 463158766Snetchild modename((int)*ip); 464158766Snetchild ip++; 465158766Snetchild narg--; 466158766Snetchild } else if (ktr->ktr_code == SYS_kill) { 467158766Snetchild print_number(ip,narg,c); 468158766Snetchild (void)putchar(','); 469158766Snetchild signame((int)*ip); 470158766Snetchild ip++; 471158766Snetchild narg--; 472158766Snetchild } else if (ktr->ktr_code == SYS_reboot) { 473158766Snetchild (void)putchar('('); 474158766Snetchild rebootoptname((int)*ip); 475158766Snetchild ip++; 476158766Snetchild narg--; 477158766Snetchild } else if (ktr->ktr_code == SYS_umask) { 478158766Snetchild (void)putchar('('); 479158766Snetchild modename((int)*ip); 480158766Snetchild ip++; 481158766Snetchild narg--; 482158766Snetchild } else if (ktr->ktr_code == SYS_msync) { 483158766Snetchild print_number(ip,narg,c); 484158766Snetchild print_number(ip,narg,c); 485158766Snetchild (void)putchar(','); 486158766Snetchild msyncflagsname((int)*ip); 487158766Snetchild ip++; 488158766Snetchild narg--; 489158766Snetchild } else if (ktr->ktr_code == SYS_mmap) { 490158766Snetchild print_number(ip,narg,c); 491158766Snetchild print_number(ip,narg,c); 492158766Snetchild (void)putchar(','); 493158766Snetchild mmapprotname ((int)*ip); 494158766Snetchild (void)putchar(','); 495158766Snetchild ip++; 496158766Snetchild narg--; 497158766Snetchild mmapflagsname ((int)*ip); 498158766Snetchild ip++; 499158766Snetchild narg--; 500158766Snetchild } else if (ktr->ktr_code == SYS_mprotect) { 501158766Snetchild print_number(ip,narg,c); 502158766Snetchild print_number(ip,narg,c); 503158766Snetchild (void)putchar(','); 504158766Snetchild mmapprotname ((int)*ip); 505158766Snetchild ip++; 506158766Snetchild narg--; 507158766Snetchild } else if (ktr->ktr_code == SYS_madvise) { 508158766Snetchild print_number(ip,narg,c); 509158766Snetchild print_number(ip,narg,c); 510158766Snetchild (void)putchar(','); 511158766Snetchild madvisebehavname((int)*ip); 512158766Snetchild ip++; 513158766Snetchild narg--; 514158766Snetchild } else if (ktr->ktr_code == SYS_setpriority) { 515158766Snetchild print_number(ip,narg,c); 516158766Snetchild print_number(ip,narg,c); 517158766Snetchild (void)putchar(','); 518158766Snetchild prioname((int)*ip); 519158766Snetchild ip++; 520158766Snetchild narg--; 521158766Snetchild } else if (ktr->ktr_code == SYS_fcntl) { 522158766Snetchild int cmd; 523158766Snetchild int arg; 524158766Snetchild print_number(ip,narg,c); 525158766Snetchild cmd = *ip; 526158766Snetchild arg = *++ip; 527158766Snetchild (void)putchar(','); 528158766Snetchild fcntlcmdname(cmd, arg, decimal); 529158766Snetchild ip++; 530158766Snetchild narg-=2; 531158766Snetchild } else if (ktr->ktr_code == SYS_socket) { 532165758Srodrigc int sockdomain; 533158766Snetchild (void)putchar('('); 534165758Srodrigc sockdomain=(int)*ip; 535165758Srodrigc sockdomainname(sockdomain); 536158766Snetchild ip++; 537158766Snetchild narg--; 538158766Snetchild (void)putchar(','); 539158766Snetchild socktypename((int)*ip); 540158766Snetchild ip++; 541158766Snetchild narg--; 542165758Srodrigc if (sockdomain == PF_INET || 543165758Srodrigc sockdomain == PF_INET6) { 544165758Srodrigc (void)putchar(','); 545165758Srodrigc sockipprotoname((int)*ip); 546165758Srodrigc ip++; 547165758Srodrigc narg--; 548165758Srodrigc } 549158766Snetchild c = ','; 550158766Snetchild } else if (ktr->ktr_code == SYS_setsockopt || 551158766Snetchild ktr->ktr_code == SYS_getsockopt) { 552158766Snetchild print_number(ip,narg,c); 553158766Snetchild (void)putchar(','); 554158766Snetchild sockoptlevelname((int)*ip, decimal); 555158766Snetchild ip++; 556158766Snetchild narg--; 557158766Snetchild (void)putchar(','); 558158766Snetchild sockoptname((int)*ip); 559158766Snetchild ip++; 560158766Snetchild narg--; 561158766Snetchild } else if (ktr->ktr_code == SYS_lseek) { 562158766Snetchild print_number(ip,narg,c); 563158766Snetchild /* Hidden 'pad' argument, not in lseek(2) */ 564158766Snetchild print_number(ip,narg,c); 565158766Snetchild print_number(ip,narg,c); 566158766Snetchild (void)putchar(','); 567158766Snetchild whencename ((int)*ip); 568158766Snetchild ip++; 569158766Snetchild narg--; 570158766Snetchild } else if (ktr->ktr_code == SYS_flock) { 571158766Snetchild print_number(ip,narg,c); 572158766Snetchild (void)putchar(','); 573158766Snetchild flockname((int)*ip); 574158766Snetchild ip++; 575158766Snetchild narg--; 576158766Snetchild } else if (ktr->ktr_code == SYS_mkfifo || 577158766Snetchild ktr->ktr_code == SYS_mkdir) { 578158766Snetchild print_number(ip,narg,c); 579158766Snetchild (void)putchar(','); 580158766Snetchild modename((int)*ip); 581158766Snetchild ip++; 582158766Snetchild narg--; 583158766Snetchild } else if (ktr->ktr_code == SYS_shutdown) { 584158766Snetchild print_number(ip,narg,c); 585158766Snetchild (void)putchar(','); 586158766Snetchild shutdownhowname((int)*ip); 587158766Snetchild ip++; 588158766Snetchild narg--; 589158766Snetchild } else if (ktr->ktr_code == SYS_socketpair) { 590158766Snetchild (void)putchar('('); 591158766Snetchild sockdomainname((int)*ip); 592158766Snetchild ip++; 593158766Snetchild narg--; 594158766Snetchild (void)putchar(','); 595158766Snetchild socktypename((int)*ip); 596158766Snetchild ip++; 597158766Snetchild narg--; 598158766Snetchild c = ','; 599158766Snetchild } else if (ktr->ktr_code == SYS_getrlimit || 600158766Snetchild ktr->ktr_code == SYS_setrlimit) { 601158766Snetchild (void)putchar('('); 602158766Snetchild rlimitname((int)*ip); 603158766Snetchild ip++; 604158766Snetchild narg--; 605158766Snetchild c = ','; 606158766Snetchild } else if (ktr->ktr_code == SYS_quotactl) { 607158766Snetchild print_number(ip,narg,c); 608158766Snetchild quotactlname((int)*ip); 609158766Snetchild ip++; 610158766Snetchild narg--; 611158766Snetchild c = ','; 612158766Snetchild } else if (ktr->ktr_code == SYS_nfssvc) { 613158766Snetchild (void)putchar('('); 614158766Snetchild nfssvcname((int)*ip); 615158766Snetchild ip++; 616158766Snetchild narg--; 617158766Snetchild c = ','; 618158766Snetchild } else if (ktr->ktr_code == SYS_rtprio) { 619158766Snetchild (void)putchar('('); 620158766Snetchild rtprioname((int)*ip); 621158766Snetchild ip++; 622158766Snetchild narg--; 623158766Snetchild c = ','; 624158766Snetchild } else if (ktr->ktr_code == SYS___semctl) { 625158766Snetchild print_number(ip,narg,c); 626158766Snetchild print_number(ip,narg,c); 627158766Snetchild semctlname((int)*ip); 628158766Snetchild ip++; 629158766Snetchild narg--; 630158766Snetchild } else if (ktr->ktr_code == SYS_semget) { 631158766Snetchild print_number(ip,narg,c); 632158766Snetchild print_number(ip,narg,c); 633158766Snetchild semgetname((int)*ip); 634158766Snetchild ip++; 635158766Snetchild narg--; 636158766Snetchild } else if (ktr->ktr_code == SYS_msgctl) { 637158766Snetchild print_number(ip,narg,c); 638158766Snetchild shmctlname((int)*ip); 639158766Snetchild ip++; 640158766Snetchild narg--; 641158766Snetchild } else if (ktr->ktr_code == SYS_shmat) { 642158766Snetchild print_number(ip,narg,c); 643158766Snetchild print_number(ip,narg,c); 644158766Snetchild shmatname((int)*ip); 645158766Snetchild ip++; 646158766Snetchild narg--; 647158766Snetchild } else if (ktr->ktr_code == SYS_shmctl) { 648158766Snetchild print_number(ip,narg,c); 649158766Snetchild shmctlname((int)*ip); 650158766Snetchild ip++; 651158766Snetchild narg--; 652158766Snetchild } else if (ktr->ktr_code == SYS_minherit) { 653158766Snetchild print_number(ip,narg,c); 654158766Snetchild print_number(ip,narg,c); 655158766Snetchild minheritname((int)*ip); 656158766Snetchild ip++; 657158766Snetchild narg--; 658158766Snetchild } else if (ktr->ktr_code == SYS_rfork) { 659158766Snetchild (void)putchar('('); 660158766Snetchild rforkname((int)*ip); 661158766Snetchild ip++; 662158766Snetchild narg--; 663158766Snetchild c = ','; 664158766Snetchild } else if (ktr->ktr_code == SYS_lio_listio) { 665158766Snetchild (void)putchar('('); 666158766Snetchild lio_listioname((int)*ip); 667158766Snetchild ip++; 668158766Snetchild narg--; 669158766Snetchild c = ','; 670158766Snetchild } else if (ktr->ktr_code == SYS_mlockall) { 671158766Snetchild (void)putchar('('); 672158766Snetchild mlockallname((int)*ip); 673158766Snetchild ip++; 674158766Snetchild narg--; 675158766Snetchild } else if (ktr->ktr_code == SYS_sched_setscheduler) { 676158766Snetchild print_number(ip,narg,c); 677158766Snetchild schedpolicyname((int)*ip); 678158766Snetchild ip++; 679158766Snetchild narg--; 680158766Snetchild } else if (ktr->ktr_code == SYS_sched_get_priority_max || 681158766Snetchild ktr->ktr_code == SYS_sched_get_priority_min) { 682158766Snetchild (void)putchar('('); 683158766Snetchild schedpolicyname((int)*ip); 684158766Snetchild ip++; 685158766Snetchild narg--; 686158766Snetchild } else if (ktr->ktr_code == SYS_sendfile) { 687158766Snetchild print_number(ip,narg,c); 688158766Snetchild print_number(ip,narg,c); 689158766Snetchild print_number(ip,narg,c); 690158766Snetchild print_number(ip,narg,c); 691158766Snetchild print_number(ip,narg,c); 692158766Snetchild print_number(ip,narg,c); 693158766Snetchild sendfileflagsname((int)*ip); 694158766Snetchild ip++; 695158766Snetchild narg--; 696158766Snetchild } else if (ktr->ktr_code == SYS_kldsym) { 697158766Snetchild print_number(ip,narg,c); 698158766Snetchild kldsymcmdname((int)*ip); 699158766Snetchild ip++; 700158766Snetchild narg--; 701158766Snetchild } else if (ktr->ktr_code == SYS_sigprocmask) { 702158766Snetchild (void)putchar('('); 703158766Snetchild sigprocmaskhowname((int)*ip); 704158766Snetchild ip++; 705158766Snetchild narg--; 706158766Snetchild c = ','; 707158766Snetchild } else if (ktr->ktr_code == SYS___acl_get_file || 708158766Snetchild ktr->ktr_code == SYS___acl_set_file || 709158766Snetchild ktr->ktr_code == SYS___acl_get_fd || 710158766Snetchild ktr->ktr_code == SYS___acl_set_fd || 711158766Snetchild ktr->ktr_code == SYS___acl_delete_file || 712158766Snetchild ktr->ktr_code == SYS___acl_delete_fd || 713158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_file || 714158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_fd || 715158766Snetchild ktr->ktr_code == SYS___acl_get_link || 716158766Snetchild ktr->ktr_code == SYS___acl_set_link || 717158766Snetchild ktr->ktr_code == SYS___acl_delete_link || 718158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_link) { 719158766Snetchild print_number(ip,narg,c); 720158766Snetchild acltypename((int)*ip); 721158766Snetchild ip++; 722158766Snetchild narg--; 723158766Snetchild } else if (ktr->ktr_code == SYS_sigaction) { 724158766Snetchild (void)putchar('('); 725158766Snetchild signame((int)*ip); 726158766Snetchild ip++; 727158766Snetchild narg--; 728158766Snetchild c = ','; 729158766Snetchild } else if (ktr->ktr_code == SYS_extattrctl) { 730158766Snetchild print_number(ip,narg,c); 731158766Snetchild extattrctlname((int)*ip); 732158766Snetchild ip++; 733158766Snetchild narg--; 734158766Snetchild } else if (ktr->ktr_code == SYS_nmount) { 735158766Snetchild print_number(ip,narg,c); 736158766Snetchild print_number(ip,narg,c); 737158766Snetchild (void)putchar(','); 738158766Snetchild mountflagsname ((int)*ip); 739158766Snetchild ip++; 740158766Snetchild narg--; 741158766Snetchild } else if (ktr->ktr_code == SYS_kse_thr_interrupt) { 742158766Snetchild print_number(ip,narg,c); 743158766Snetchild (void)putchar(','); 744158766Snetchild ksethrcmdname ((int)*ip); 745158766Snetchild ip++; 746158766Snetchild narg--; 747158766Snetchild } else if (ktr->ktr_code == SYS_thr_create) { 748158766Snetchild print_number(ip,narg,c); 749158766Snetchild print_number(ip,narg,c); 750158766Snetchild (void)putchar(','); 751158766Snetchild thrcreateflagsname ((int)*ip); 752158766Snetchild ip++; 753158766Snetchild narg--; 754158766Snetchild } else if (ktr->ktr_code == SYS_thr_kill) { 755158766Snetchild print_number(ip,narg,c); 756158766Snetchild (void)putchar(','); 757158766Snetchild signame ((int)*ip); 758158766Snetchild ip++; 759158766Snetchild narg--; 760158766Snetchild } else if (ktr->ktr_code == SYS_kldunloadf) { 761158766Snetchild print_number(ip,narg,c); 762158766Snetchild (void)putchar(','); 763158766Snetchild kldunloadfflagsname ((int)*ip); 764158766Snetchild ip++; 765158766Snetchild narg--; 7661590Srgrimes } 7671590Srgrimes } 7681590Srgrimes while (narg) { 769158766Snetchild print_number(ip,narg,c); 7701590Srgrimes } 7711590Srgrimes (void)putchar(')'); 7721590Srgrimes } 7731590Srgrimes (void)putchar('\n'); 7741590Srgrimes} 7751590Srgrimes 776100824Sdwmalonevoid 777100824Sdwmalonektrsysret(struct ktr_sysret *ktr) 7781590Srgrimes{ 779100824Sdwmalone register_t ret = ktr->ktr_retval; 780100824Sdwmalone int error = ktr->ktr_error; 781100824Sdwmalone int code = ktr->ktr_code; 7821590Srgrimes 7831590Srgrimes if (code >= nsyscalls || code < 0) 7841590Srgrimes (void)printf("[%d] ", code); 7851590Srgrimes else 7861590Srgrimes (void)printf("%s ", syscallnames[code]); 7871590Srgrimes 7881590Srgrimes if (error == 0) { 7891590Srgrimes if (fancy) { 7901590Srgrimes (void)printf("%d", ret); 7911590Srgrimes if (ret < 0 || ret > 9) 79247957Sdt (void)printf("/%#lx", (long)ret); 7931590Srgrimes } else { 7941590Srgrimes if (decimal) 79547957Sdt (void)printf("%ld", (long)ret); 7961590Srgrimes else 79747957Sdt (void)printf("%#lx", (long)ret); 7981590Srgrimes } 7991590Srgrimes } else if (error == ERESTART) 8001590Srgrimes (void)printf("RESTART"); 8011590Srgrimes else if (error == EJUSTRETURN) 8021590Srgrimes (void)printf("JUSTRETURN"); 8031590Srgrimes else { 8041590Srgrimes (void)printf("-1 errno %d", ktr->ktr_error); 8051590Srgrimes if (fancy) 8061590Srgrimes (void)printf(" %s", strerror(ktr->ktr_error)); 8071590Srgrimes } 8081590Srgrimes (void)putchar('\n'); 8091590Srgrimes} 8101590Srgrimes 811100824Sdwmalonevoid 812100824Sdwmalonektrnamei(char *cp, int len) 8131590Srgrimes{ 8141590Srgrimes (void)printf("\"%.*s\"\n", len, cp); 8151590Srgrimes} 8161590Srgrimes 817100824Sdwmalonevoid 818115759Speterhexdump(char *p, int len, int screenwidth) 8191590Srgrimes{ 820115759Speter int n, i; 821115759Speter int width; 822115759Speter 823115759Speter width = 0; 824115759Speter do { 825115759Speter width += 2; 826115759Speter i = 13; /* base offset */ 827115759Speter i += (width / 2) + 1; /* spaces every second byte */ 828115759Speter i += (width * 2); /* width of bytes */ 829115759Speter i += 3; /* " |" */ 830115759Speter i += width; /* each byte */ 831115759Speter i += 1; /* "|" */ 832115759Speter } while (i < screenwidth); 833115759Speter width -= 2; 834115759Speter 835115759Speter for (n = 0; n < len; n += width) { 836115759Speter for (i = n; i < n + width; i++) { 837115759Speter if ((i % width) == 0) { /* beginning of line */ 838115759Speter printf(" 0x%04x", i); 839115759Speter } 840115759Speter if ((i % 2) == 0) { 841115759Speter printf(" "); 842115759Speter } 843115759Speter if (i < len) 844115759Speter printf("%02x", p[i] & 0xff); 845115759Speter else 846115759Speter printf(" "); 847115759Speter } 848115759Speter printf(" |"); 849115759Speter for (i = n; i < n + width; i++) { 850115759Speter if (i >= len) 851115759Speter break; 852115759Speter if (p[i] >= ' ' && p[i] <= '~') 853115759Speter printf("%c", p[i]); 854115759Speter else 855115759Speter printf("."); 856115759Speter } 857115759Speter printf("|\n"); 858115759Speter } 859115759Speter if ((i % width) != 0) 860115759Speter printf("\n"); 861115759Speter} 862115759Speter 863115759Spetervoid 864115759Spetervisdump(char *dp, int datalen, int screenwidth) 865115759Speter{ 866115759Speter int col = 0; 867100824Sdwmalone char *cp; 868100824Sdwmalone int width; 8691590Srgrimes char visbuf[5]; 8701590Srgrimes 8711590Srgrimes (void)printf(" \""); 8721590Srgrimes col = 8; 8731590Srgrimes for (;datalen > 0; datalen--, dp++) { 8741590Srgrimes (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 8751590Srgrimes cp = visbuf; 8761590Srgrimes /* 8771590Srgrimes * Keep track of printables and 8781590Srgrimes * space chars (like fold(1)). 8791590Srgrimes */ 8801590Srgrimes if (col == 0) { 8811590Srgrimes (void)putchar('\t'); 8821590Srgrimes col = 8; 8831590Srgrimes } 8841590Srgrimes switch(*cp) { 8851590Srgrimes case '\n': 8861590Srgrimes col = 0; 8871590Srgrimes (void)putchar('\n'); 8881590Srgrimes continue; 8891590Srgrimes case '\t': 8901590Srgrimes width = 8 - (col&07); 8911590Srgrimes break; 8921590Srgrimes default: 8931590Srgrimes width = strlen(cp); 8941590Srgrimes } 8951590Srgrimes if (col + width > (screenwidth-2)) { 8961590Srgrimes (void)printf("\\\n\t"); 8971590Srgrimes col = 8; 8981590Srgrimes } 8991590Srgrimes col += width; 9001590Srgrimes do { 9011590Srgrimes (void)putchar(*cp++); 9021590Srgrimes } while (*cp); 9031590Srgrimes } 9041590Srgrimes if (col == 0) 9051590Srgrimes (void)printf(" "); 9061590Srgrimes (void)printf("\"\n"); 9071590Srgrimes} 9081590Srgrimes 909115759Spetervoid 910115759Speterktrgenio(struct ktr_genio *ktr, int len) 911115759Speter{ 912115759Speter int datalen = len - sizeof (struct ktr_genio); 913115759Speter char *dp = (char *)ktr + sizeof (struct ktr_genio); 914115759Speter static int screenwidth = 0; 915115759Speter int i, binary; 916115759Speter 917115759Speter if (screenwidth == 0) { 918115759Speter struct winsize ws; 919115759Speter 920115759Speter if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 921115759Speter ws.ws_col > 8) 922115759Speter screenwidth = ws.ws_col; 923115759Speter else 924115759Speter screenwidth = 80; 925115759Speter } 926115759Speter printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 927115759Speter ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 928115759Speter datalen == 1 ? "" : "s"); 929152331Srwatson if (suppressdata) 930152331Srwatson return; 931115759Speter if (maxdata && datalen > maxdata) 932115759Speter datalen = maxdata; 933115759Speter 934115759Speter for (i = 0, binary = 0; i < datalen && binary == 0; i++) { 935115759Speter if (dp[i] >= 32 && dp[i] < 127) 936115759Speter continue; 937115759Speter if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9) 938115759Speter continue; 939115759Speter binary = 1; 940115759Speter } 941115759Speter if (binary) 942115759Speter hexdump(dp, datalen, screenwidth); 943115759Speter else 944115759Speter visdump(dp, datalen, screenwidth); 945115759Speter} 946115759Speter 947100824Sdwmaloneconst char *signames[] = { 9481590Srgrimes "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 9491590Srgrimes "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 9501590Srgrimes "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 9511590Srgrimes "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 9521590Srgrimes "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 9531590Srgrimes "USR2", NULL, /* 31 - 32 */ 9541590Srgrimes}; 9551590Srgrimes 956100824Sdwmalonevoid 957100824Sdwmalonektrpsig(struct ktr_psig *psig) 9581590Srgrimes{ 959160294Skib if (psig->signo > 0 && psig->signo < NSIG) 960160296Smaxim (void)printf("SIG%s ", signames[psig->signo]); 961160294Skib else 962160296Smaxim (void)printf("SIG %d ", psig->signo); 9631590Srgrimes if (psig->action == SIG_DFL) 9641590Srgrimes (void)printf("SIG_DFL\n"); 965100824Sdwmalone else { 96647957Sdt (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 967100824Sdwmalone (u_long)psig->action, psig->mask.__bits[0], psig->code); 968100824Sdwmalone } 9691590Srgrimes} 9701590Srgrimes 971100824Sdwmalonevoid 972100824Sdwmalonektrcsw(struct ktr_csw *cs) 9731590Srgrimes{ 9741590Srgrimes (void)printf("%s %s\n", cs->out ? "stop" : "resume", 9751590Srgrimes cs->user ? "user" : "kernel"); 9761590Srgrimes} 9771590Srgrimes 978100824Sdwmalonevoid 979100824Sdwmalonektruser(int len, unsigned char *p) 98018400Sphk{ 98118470Sphk (void)printf("%d ", len); 98218470Sphk while (len--) 983127402Sphk if (decimal) 984127402Sphk (void)printf(" %d", *p++); 985127402Sphk else 986127402Sphk (void)printf(" %02x", *p++); 98718400Sphk (void)printf("\n"); 98818400Sphk 98918400Sphk} 99018400Sphk 991100824Sdwmalonevoid 992100824Sdwmaloneusage(void) 9931590Srgrimes{ 9941590Srgrimes (void)fprintf(stderr, 995152331Srwatson "usage: kdump [-dEnlHRsT] [-f trfile] [-m maxdata] [-p pid] [-t [cnisuw]]\n"); 9961590Srgrimes exit(1); 9971590Srgrimes} 998