kdump.c revision 160294
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 160294 2006-07-12 12:41:56Z kib $"); 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> 6127443Scharnier#include <err.h> 6227443Scharnier#include <locale.h> 631590Srgrimes#include <stdio.h> 641590Srgrimes#include <stdlib.h> 651590Srgrimes#include <string.h> 6627443Scharnier#include <unistd.h> 6727443Scharnier#include <vis.h> 681590Srgrimes#include "ktrace.h" 69158766Snetchild#include "kdump_subr.h" 701590Srgrimes 71100824Sdwmaloneint fread_tail(void *, int, int); 72100824Sdwmalonevoid dumpheader(struct ktr_header *); 73100824Sdwmalonevoid ktrsyscall(struct ktr_syscall *); 74100824Sdwmalonevoid ktrsysret(struct ktr_sysret *); 75100824Sdwmalonevoid ktrnamei(char *, int); 76115759Spetervoid hexdump(char *, int, int); 77115759Spetervoid visdump(char *, int, int); 78100824Sdwmalonevoid ktrgenio(struct ktr_genio *, int); 79100824Sdwmalonevoid ktrpsig(struct ktr_psig *); 80100824Sdwmalonevoid ktrcsw(struct ktr_csw *); 81100824Sdwmalonevoid ktruser(int, unsigned char *); 82100824Sdwmalonevoid usage(void); 83135466Sruconst char *ioctlname(u_long); 84100824Sdwmalone 85152331Srwatsonint timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata; 86100824Sdwmaloneconst char *tracefile = DEF_TRACEFILE; 871590Srgrimesstruct ktr_header ktr_header; 881590Srgrimes 891590Srgrimes#define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 901590Srgrimes 91100824Sdwmaloneint 92100824Sdwmalonemain(int argc, char *argv[]) 931590Srgrimes{ 941590Srgrimes int ch, ktrlen, size; 95100824Sdwmalone void *m; 961590Srgrimes int trpoints = ALL_POINTS; 97112201Sjhb int drop_logged; 98115759Speter pid_t pid = 0; 991590Srgrimes 10011823Sache (void) setlocale(LC_CTYPE, ""); 10111823Sache 102152331Srwatson while ((ch = getopt(argc,argv,"f:dElm:np:HRsTt:")) != -1) 1031590Srgrimes switch((char)ch) { 1041590Srgrimes case 'f': 1051590Srgrimes tracefile = optarg; 1061590Srgrimes break; 1071590Srgrimes case 'd': 1081590Srgrimes decimal = 1; 1091590Srgrimes break; 1101590Srgrimes case 'l': 1111590Srgrimes tail = 1; 1121590Srgrimes break; 1131590Srgrimes case 'm': 1141590Srgrimes maxdata = atoi(optarg); 1151590Srgrimes break; 1161590Srgrimes case 'n': 1171590Srgrimes fancy = 0; 1181590Srgrimes break; 119115759Speter case 'p': 120115759Speter pid = atoi(optarg); 121115759Speter break; 122152331Srwatson case 's': 123152331Srwatson suppressdata = 1; 124152331Srwatson break; 125123187Speter case 'E': 126123187Speter timestamp = 3; /* elapsed timestamp */ 127123187Speter break; 128151930Srwatson case 'H': 129151930Srwatson threads = 1; 130151930Srwatson break; 1311590Srgrimes case 'R': 1321590Srgrimes timestamp = 2; /* relative timestamp */ 1331590Srgrimes break; 1341590Srgrimes case 'T': 1351590Srgrimes timestamp = 1; 1361590Srgrimes break; 1371590Srgrimes case 't': 1381590Srgrimes trpoints = getpoints(optarg); 13927443Scharnier if (trpoints < 0) 14027443Scharnier errx(1, "unknown trace point in %s", optarg); 1411590Srgrimes break; 1421590Srgrimes default: 1431590Srgrimes usage(); 1441590Srgrimes } 1451590Srgrimes 14619853Sfenner if (argc > optind) 1471590Srgrimes usage(); 1481590Srgrimes 1491590Srgrimes m = (void *)malloc(size = 1025); 15027443Scharnier if (m == NULL) 15127443Scharnier errx(1, "%s", strerror(ENOMEM)); 15227443Scharnier if (!freopen(tracefile, "r", stdin)) 15327443Scharnier err(1, "%s", tracefile); 154112201Sjhb drop_logged = 0; 1551590Srgrimes while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 156112201Sjhb if (ktr_header.ktr_type & KTR_DROP) { 157112201Sjhb ktr_header.ktr_type &= ~KTR_DROP; 158151930Srwatson if (!drop_logged && threads) { 159151930Srwatson (void)printf("%6d %6d %-8.*s Events dropped.\n", 160151930Srwatson ktr_header.ktr_pid, ktr_header.ktr_tid > 161151930Srwatson 0 ? ktr_header.ktr_tid : 0, MAXCOMLEN, 162151930Srwatson ktr_header.ktr_comm); 163151930Srwatson drop_logged = 1; 164151930Srwatson } else if (!drop_logged) { 165112201Sjhb (void)printf("%6d %-8.*s Events dropped.\n", 166112201Sjhb ktr_header.ktr_pid, MAXCOMLEN, 167112201Sjhb ktr_header.ktr_comm); 168112201Sjhb drop_logged = 1; 169112201Sjhb } 170112201Sjhb } 1711590Srgrimes if (trpoints & (1<<ktr_header.ktr_type)) 172115759Speter if (pid == 0 || ktr_header.ktr_pid == pid) 173115759Speter dumpheader(&ktr_header); 17427443Scharnier if ((ktrlen = ktr_header.ktr_len) < 0) 17527443Scharnier errx(1, "bogus length 0x%x", ktrlen); 1761590Srgrimes if (ktrlen > size) { 1771590Srgrimes m = (void *)realloc(m, ktrlen+1); 17827443Scharnier if (m == NULL) 17927443Scharnier errx(1, "%s", strerror(ENOMEM)); 1801590Srgrimes size = ktrlen; 1811590Srgrimes } 18227443Scharnier if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 18327443Scharnier errx(1, "data too short"); 184115759Speter if (pid && ktr_header.ktr_pid != pid) 185115759Speter continue; 1861590Srgrimes if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 1871590Srgrimes continue; 188112201Sjhb drop_logged = 0; 1891590Srgrimes switch (ktr_header.ktr_type) { 1901590Srgrimes case KTR_SYSCALL: 1911590Srgrimes ktrsyscall((struct ktr_syscall *)m); 1921590Srgrimes break; 1931590Srgrimes case KTR_SYSRET: 1941590Srgrimes ktrsysret((struct ktr_sysret *)m); 1951590Srgrimes break; 1961590Srgrimes case KTR_NAMEI: 1971590Srgrimes ktrnamei(m, ktrlen); 1981590Srgrimes break; 1991590Srgrimes case KTR_GENIO: 2001590Srgrimes ktrgenio((struct ktr_genio *)m, ktrlen); 2011590Srgrimes break; 2021590Srgrimes case KTR_PSIG: 2031590Srgrimes ktrpsig((struct ktr_psig *)m); 2041590Srgrimes break; 2051590Srgrimes case KTR_CSW: 2061590Srgrimes ktrcsw((struct ktr_csw *)m); 2071590Srgrimes break; 20818400Sphk case KTR_USER: 20918470Sphk ktruser(ktrlen, m); 21018400Sphk break; 211112203Sjhb default: 212112203Sjhb printf("\n"); 213112203Sjhb break; 2141590Srgrimes } 2151590Srgrimes if (tail) 2161590Srgrimes (void)fflush(stdout); 2171590Srgrimes } 218100824Sdwmalone return 0; 2191590Srgrimes} 2201590Srgrimes 221100824Sdwmaloneint 222100824Sdwmalonefread_tail(void *buf, int size, int num) 2231590Srgrimes{ 2241590Srgrimes int i; 2251590Srgrimes 2261590Srgrimes while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 2271590Srgrimes (void)sleep(1); 2281590Srgrimes clearerr(stdin); 2291590Srgrimes } 2301590Srgrimes return (i); 2311590Srgrimes} 2321590Srgrimes 233100824Sdwmalonevoid 234100824Sdwmalonedumpheader(struct ktr_header *kth) 2351590Srgrimes{ 2361590Srgrimes static char unknown[64]; 2371590Srgrimes static struct timeval prevtime, temp; 238100824Sdwmalone const char *type; 2391590Srgrimes 2401590Srgrimes switch (kth->ktr_type) { 2411590Srgrimes case KTR_SYSCALL: 2421590Srgrimes type = "CALL"; 2431590Srgrimes break; 2441590Srgrimes case KTR_SYSRET: 2451590Srgrimes type = "RET "; 2461590Srgrimes break; 2471590Srgrimes case KTR_NAMEI: 2481590Srgrimes type = "NAMI"; 2491590Srgrimes break; 2501590Srgrimes case KTR_GENIO: 2511590Srgrimes type = "GIO "; 2521590Srgrimes break; 2531590Srgrimes case KTR_PSIG: 2541590Srgrimes type = "PSIG"; 2551590Srgrimes break; 2561590Srgrimes case KTR_CSW: 2571590Srgrimes type = "CSW"; 2581590Srgrimes break; 25918400Sphk case KTR_USER: 26018400Sphk type = "USER"; 26118400Sphk break; 2621590Srgrimes default: 2631590Srgrimes (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 2641590Srgrimes type = unknown; 2651590Srgrimes } 2661590Srgrimes 267151930Srwatson /* 268151930Srwatson * The ktr_tid field was previously the ktr_buffer field, which held 269151930Srwatson * the kernel pointer value for the buffer associated with data 270151930Srwatson * following the record header. It now holds a threadid, but only 271151930Srwatson * for trace files after the change. Older trace files still contain 272151930Srwatson * kernel pointers. Detect this and suppress the results by printing 273151930Srwatson * negative tid's as 0. 274151930Srwatson */ 275151930Srwatson if (threads) 276151930Srwatson (void)printf("%6d %6d %-8.*s ", kth->ktr_pid, kth->ktr_tid > 277151930Srwatson 0 ? kth->ktr_tid : 0, MAXCOMLEN, kth->ktr_comm); 278151930Srwatson else 279151930Srwatson (void)printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN, 280151930Srwatson kth->ktr_comm); 2811590Srgrimes if (timestamp) { 282123187Speter if (timestamp == 3) { 283123187Speter if (prevtime.tv_sec == 0) 284123187Speter prevtime = kth->ktr_time; 285123187Speter timevalsub(&kth->ktr_time, &prevtime); 286123187Speter } 2871590Srgrimes if (timestamp == 2) { 2881590Srgrimes temp = kth->ktr_time; 2891590Srgrimes timevalsub(&kth->ktr_time, &prevtime); 2901590Srgrimes prevtime = temp; 2911590Srgrimes } 2921590Srgrimes (void)printf("%ld.%06ld ", 2931590Srgrimes kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); 2941590Srgrimes } 2951590Srgrimes (void)printf("%s ", type); 2961590Srgrimes} 2971590Srgrimes 2981590Srgrimes#include <sys/syscall.h> 2991590Srgrimes#define KTRACE 3004721Sphk#include <sys/kern/syscalls.c> 3011590Srgrimes#undef KTRACE 3021590Srgrimesint nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 3031590Srgrimes 304100824Sdwmalonestatic const char *ptrace_ops[] = { 3051590Srgrimes "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U", 3061590Srgrimes "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE", 30748234Sbde "PT_KILL", "PT_STEP", "PT_ATTACH", "PT_DETACH", 3081590Srgrimes}; 3091590Srgrimes 310100824Sdwmalonevoid 311100824Sdwmalonektrsyscall(struct ktr_syscall *ktr) 3121590Srgrimes{ 313100824Sdwmalone int narg = ktr->ktr_narg; 314100824Sdwmalone register_t *ip; 3151590Srgrimes 3161590Srgrimes if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) 3171590Srgrimes (void)printf("[%d]", ktr->ktr_code); 3181590Srgrimes else 3191590Srgrimes (void)printf("%s", syscallnames[ktr->ktr_code]); 32047957Sdt ip = &ktr->ktr_args[0]; 3211590Srgrimes if (narg) { 3221590Srgrimes char c = '('; 3231590Srgrimes if (fancy) { 324158766Snetchild 325158766Snetchild#define print_number(i,n,c) do { \ 326158766Snetchild if (decimal) \ 327158766Snetchild (void)printf("%c%ld", c, (long)*i); \ 328158766Snetchild else \ 329158766Snetchild (void)printf("%c%#lx", c, (long)*i); \ 330158766Snetchild i++; \ 331158766Snetchild n--; \ 332158766Snetchild c = ','; \ 333158766Snetchild } while (0); 334158766Snetchild 3351590Srgrimes if (ktr->ktr_code == SYS_ioctl) { 336100824Sdwmalone const char *cp; 337158766Snetchild print_number(ip,narg,c); 3381590Srgrimes if ((cp = ioctlname(*ip)) != NULL) 3391590Srgrimes (void)printf(",%s", cp); 3401590Srgrimes else { 3411590Srgrimes if (decimal) 34247957Sdt (void)printf(",%ld", (long)*ip); 3431590Srgrimes else 34447957Sdt (void)printf(",%#lx ", (long)*ip); 3451590Srgrimes } 3461590Srgrimes c = ','; 3471590Srgrimes ip++; 3481590Srgrimes narg--; 3491590Srgrimes } else if (ktr->ktr_code == SYS_ptrace) { 350100824Sdwmalone if ((size_t)*ip < sizeof(ptrace_ops) / 35148234Sbde sizeof(ptrace_ops[0]) && *ip >= 0) 3521590Srgrimes (void)printf("(%s", ptrace_ops[*ip]); 35348234Sbde#ifdef PT_GETREGS 35448234Sbde else if (*ip == PT_GETREGS) 35548234Sbde (void)printf("(%s", "PT_GETREGS"); 35648234Sbde#endif 35748234Sbde#ifdef PT_SETREGS 35848234Sbde else if (*ip == PT_SETREGS) 35948234Sbde (void)printf("(%s", "PT_SETREGS"); 36048234Sbde#endif 36148234Sbde#ifdef PT_GETFPREGS 36248234Sbde else if (*ip == PT_GETFPREGS) 36348234Sbde (void)printf("(%s", "PT_GETFPREGS"); 36448234Sbde#endif 36548234Sbde#ifdef PT_SETFPREGS 36648234Sbde else if (*ip == PT_SETFPREGS) 36748234Sbde (void)printf("(%s", "PT_SETFPREGS"); 36848234Sbde#endif 36948852Sbde#ifdef PT_GETDBREGS 37048852Sbde else if (*ip == PT_GETDBREGS) 37148852Sbde (void)printf("(%s", "PT_GETDBREGS"); 37248852Sbde#endif 37348852Sbde#ifdef PT_SETDBREGS 37448852Sbde else if (*ip == PT_SETDBREGS) 37548852Sbde (void)printf("(%s", "PT_SETDBREGS"); 37648852Sbde#endif 3771590Srgrimes else 37847957Sdt (void)printf("(%ld", (long)*ip); 3791590Srgrimes c = ','; 3801590Srgrimes ip++; 3811590Srgrimes narg--; 382158766Snetchild } else if (ktr->ktr_code == SYS_access || 383158766Snetchild ktr->ktr_code == SYS_eaccess) { 384158766Snetchild print_number(ip,narg,c); 385158766Snetchild (void)putchar(','); 386158766Snetchild accessmodename ((int)*ip); 387158766Snetchild ip++; 388158766Snetchild narg--; 389158766Snetchild } else if (ktr->ktr_code == SYS_open) { 390158766Snetchild int flags; 391158766Snetchild int mode; 392158766Snetchild print_number(ip,narg,c); 393158766Snetchild flags = *ip; 394158766Snetchild mode = *++ip; 395158766Snetchild (void)putchar(','); 396158766Snetchild flagsandmodename (flags, mode, decimal); 397158766Snetchild ip++; 398158766Snetchild narg-=2; 399158766Snetchild } else if (ktr->ktr_code == SYS_wait4) { 400158766Snetchild print_number(ip,narg,c); 401158766Snetchild print_number(ip,narg,c); 402158766Snetchild (void)putchar(','); 403158766Snetchild wait4optname ((int)*ip); 404158766Snetchild ip++; 405158766Snetchild narg--; 406158766Snetchild } else if (ktr->ktr_code == SYS_chmod || 407158766Snetchild ktr->ktr_code == SYS_fchmod || 408158766Snetchild ktr->ktr_code == SYS_lchmod) { 409158766Snetchild print_number(ip,narg,c); 410158766Snetchild (void)putchar(','); 411158766Snetchild modename ((int)*ip); 412158766Snetchild ip++; 413158766Snetchild narg--; 414158766Snetchild } else if (ktr->ktr_code == SYS_mknod) { 415158766Snetchild print_number(ip,narg,c); 416158766Snetchild (void)putchar(','); 417158766Snetchild modename ((int)*ip); 418158766Snetchild ip++; 419158766Snetchild narg--; 420158766Snetchild } else if (ktr->ktr_code == SYS_getfsstat) { 421158766Snetchild print_number(ip,narg,c); 422158766Snetchild print_number(ip,narg,c); 423158766Snetchild (void)putchar(','); 424158766Snetchild getfsstatflagsname ((int)*ip); 425158766Snetchild ip++; 426158766Snetchild narg--; 427158766Snetchild } else if (ktr->ktr_code == SYS_mount) { 428158766Snetchild print_number(ip,narg,c); 429158766Snetchild print_number(ip,narg,c); 430158766Snetchild (void)putchar(','); 431158766Snetchild mountflagsname ((int)*ip); 432158766Snetchild ip++; 433158766Snetchild narg--; 434158766Snetchild } else if (ktr->ktr_code == SYS_unmount) { 435158766Snetchild print_number(ip,narg,c); 436158766Snetchild (void)putchar(','); 437158766Snetchild mountflagsname ((int)*ip); 438158766Snetchild ip++; 439158766Snetchild narg--; 440158766Snetchild } else if (ktr->ktr_code == SYS_recvmsg || 441158766Snetchild ktr->ktr_code == SYS_sendmsg) { 442158766Snetchild print_number(ip,narg,c); 443158766Snetchild print_number(ip,narg,c); 444158766Snetchild (void)putchar(','); 445158766Snetchild sendrecvflagsname ((int)*ip); 446158766Snetchild ip++; 447158766Snetchild narg--; 448158766Snetchild } else if (ktr->ktr_code == SYS_recvfrom || 449158766Snetchild ktr->ktr_code == SYS_sendto) { 450158766Snetchild print_number(ip,narg,c); 451158766Snetchild print_number(ip,narg,c); 452158766Snetchild print_number(ip,narg,c); 453158766Snetchild (void)putchar(','); 454158766Snetchild sendrecvflagsname ((int)*ip); 455158766Snetchild ip++; 456158766Snetchild narg--; 457158766Snetchild } else if (ktr->ktr_code == SYS_chflags || 458158766Snetchild ktr->ktr_code == SYS_fchflags || 459158766Snetchild ktr->ktr_code == SYS_lchflags) { 460158766Snetchild print_number(ip,narg,c); 461158766Snetchild (void)putchar(','); 462158766Snetchild modename((int)*ip); 463158766Snetchild ip++; 464158766Snetchild narg--; 465158766Snetchild } else if (ktr->ktr_code == SYS_kill) { 466158766Snetchild print_number(ip,narg,c); 467158766Snetchild (void)putchar(','); 468158766Snetchild signame((int)*ip); 469158766Snetchild ip++; 470158766Snetchild narg--; 471158766Snetchild } else if (ktr->ktr_code == SYS_reboot) { 472158766Snetchild (void)putchar('('); 473158766Snetchild rebootoptname((int)*ip); 474158766Snetchild ip++; 475158766Snetchild narg--; 476158766Snetchild } else if (ktr->ktr_code == SYS_umask) { 477158766Snetchild (void)putchar('('); 478158766Snetchild modename((int)*ip); 479158766Snetchild ip++; 480158766Snetchild narg--; 481158766Snetchild } else if (ktr->ktr_code == SYS_msync) { 482158766Snetchild print_number(ip,narg,c); 483158766Snetchild print_number(ip,narg,c); 484158766Snetchild (void)putchar(','); 485158766Snetchild msyncflagsname((int)*ip); 486158766Snetchild ip++; 487158766Snetchild narg--; 488158766Snetchild } else if (ktr->ktr_code == SYS_mmap) { 489158766Snetchild print_number(ip,narg,c); 490158766Snetchild print_number(ip,narg,c); 491158766Snetchild (void)putchar(','); 492158766Snetchild mmapprotname ((int)*ip); 493158766Snetchild (void)putchar(','); 494158766Snetchild ip++; 495158766Snetchild narg--; 496158766Snetchild mmapflagsname ((int)*ip); 497158766Snetchild ip++; 498158766Snetchild narg--; 499158766Snetchild } else if (ktr->ktr_code == SYS_mprotect) { 500158766Snetchild print_number(ip,narg,c); 501158766Snetchild print_number(ip,narg,c); 502158766Snetchild (void)putchar(','); 503158766Snetchild mmapprotname ((int)*ip); 504158766Snetchild ip++; 505158766Snetchild narg--; 506158766Snetchild } else if (ktr->ktr_code == SYS_madvise) { 507158766Snetchild print_number(ip,narg,c); 508158766Snetchild print_number(ip,narg,c); 509158766Snetchild (void)putchar(','); 510158766Snetchild madvisebehavname((int)*ip); 511158766Snetchild ip++; 512158766Snetchild narg--; 513158766Snetchild } else if (ktr->ktr_code == SYS_setpriority) { 514158766Snetchild print_number(ip,narg,c); 515158766Snetchild print_number(ip,narg,c); 516158766Snetchild (void)putchar(','); 517158766Snetchild prioname((int)*ip); 518158766Snetchild ip++; 519158766Snetchild narg--; 520158766Snetchild } else if (ktr->ktr_code == SYS_fcntl) { 521158766Snetchild int cmd; 522158766Snetchild int arg; 523158766Snetchild print_number(ip,narg,c); 524158766Snetchild cmd = *ip; 525158766Snetchild arg = *++ip; 526158766Snetchild (void)putchar(','); 527158766Snetchild fcntlcmdname(cmd, arg, decimal); 528158766Snetchild ip++; 529158766Snetchild narg-=2; 530158766Snetchild } else if (ktr->ktr_code == SYS_socket) { 531158766Snetchild (void)putchar('('); 532158766Snetchild sockdomainname((int)*ip); 533158766Snetchild ip++; 534158766Snetchild narg--; 535158766Snetchild (void)putchar(','); 536158766Snetchild socktypename((int)*ip); 537158766Snetchild ip++; 538158766Snetchild narg--; 539158766Snetchild c = ','; 540158766Snetchild } else if (ktr->ktr_code == SYS_setsockopt || 541158766Snetchild ktr->ktr_code == SYS_getsockopt) { 542158766Snetchild print_number(ip,narg,c); 543158766Snetchild (void)putchar(','); 544158766Snetchild sockoptlevelname((int)*ip, decimal); 545158766Snetchild ip++; 546158766Snetchild narg--; 547158766Snetchild (void)putchar(','); 548158766Snetchild sockoptname((int)*ip); 549158766Snetchild ip++; 550158766Snetchild narg--; 551158766Snetchild } else if (ktr->ktr_code == SYS_lseek) { 552158766Snetchild print_number(ip,narg,c); 553158766Snetchild /* Hidden 'pad' argument, not in lseek(2) */ 554158766Snetchild print_number(ip,narg,c); 555158766Snetchild print_number(ip,narg,c); 556158766Snetchild (void)putchar(','); 557158766Snetchild whencename ((int)*ip); 558158766Snetchild ip++; 559158766Snetchild narg--; 560158766Snetchild } else if (ktr->ktr_code == SYS_flock) { 561158766Snetchild print_number(ip,narg,c); 562158766Snetchild (void)putchar(','); 563158766Snetchild flockname((int)*ip); 564158766Snetchild ip++; 565158766Snetchild narg--; 566158766Snetchild } else if (ktr->ktr_code == SYS_mkfifo || 567158766Snetchild ktr->ktr_code == SYS_mkdir) { 568158766Snetchild print_number(ip,narg,c); 569158766Snetchild (void)putchar(','); 570158766Snetchild modename((int)*ip); 571158766Snetchild ip++; 572158766Snetchild narg--; 573158766Snetchild } else if (ktr->ktr_code == SYS_shutdown) { 574158766Snetchild print_number(ip,narg,c); 575158766Snetchild (void)putchar(','); 576158766Snetchild shutdownhowname((int)*ip); 577158766Snetchild ip++; 578158766Snetchild narg--; 579158766Snetchild } else if (ktr->ktr_code == SYS_socketpair) { 580158766Snetchild (void)putchar('('); 581158766Snetchild sockdomainname((int)*ip); 582158766Snetchild ip++; 583158766Snetchild narg--; 584158766Snetchild (void)putchar(','); 585158766Snetchild socktypename((int)*ip); 586158766Snetchild ip++; 587158766Snetchild narg--; 588158766Snetchild c = ','; 589158766Snetchild } else if (ktr->ktr_code == SYS_getrlimit || 590158766Snetchild ktr->ktr_code == SYS_setrlimit) { 591158766Snetchild (void)putchar('('); 592158766Snetchild rlimitname((int)*ip); 593158766Snetchild ip++; 594158766Snetchild narg--; 595158766Snetchild c = ','; 596158766Snetchild } else if (ktr->ktr_code == SYS_quotactl) { 597158766Snetchild print_number(ip,narg,c); 598158766Snetchild quotactlname((int)*ip); 599158766Snetchild ip++; 600158766Snetchild narg--; 601158766Snetchild c = ','; 602158766Snetchild } else if (ktr->ktr_code == SYS_nfssvc) { 603158766Snetchild (void)putchar('('); 604158766Snetchild nfssvcname((int)*ip); 605158766Snetchild ip++; 606158766Snetchild narg--; 607158766Snetchild c = ','; 608158766Snetchild } else if (ktr->ktr_code == SYS_rtprio) { 609158766Snetchild (void)putchar('('); 610158766Snetchild rtprioname((int)*ip); 611158766Snetchild ip++; 612158766Snetchild narg--; 613158766Snetchild c = ','; 614158766Snetchild } else if (ktr->ktr_code == SYS___semctl) { 615158766Snetchild print_number(ip,narg,c); 616158766Snetchild print_number(ip,narg,c); 617158766Snetchild semctlname((int)*ip); 618158766Snetchild ip++; 619158766Snetchild narg--; 620158766Snetchild } else if (ktr->ktr_code == SYS_semget) { 621158766Snetchild print_number(ip,narg,c); 622158766Snetchild print_number(ip,narg,c); 623158766Snetchild semgetname((int)*ip); 624158766Snetchild ip++; 625158766Snetchild narg--; 626158766Snetchild } else if (ktr->ktr_code == SYS_msgctl) { 627158766Snetchild print_number(ip,narg,c); 628158766Snetchild shmctlname((int)*ip); 629158766Snetchild ip++; 630158766Snetchild narg--; 631158766Snetchild } else if (ktr->ktr_code == SYS_shmat) { 632158766Snetchild print_number(ip,narg,c); 633158766Snetchild print_number(ip,narg,c); 634158766Snetchild shmatname((int)*ip); 635158766Snetchild ip++; 636158766Snetchild narg--; 637158766Snetchild } else if (ktr->ktr_code == SYS_shmctl) { 638158766Snetchild print_number(ip,narg,c); 639158766Snetchild shmctlname((int)*ip); 640158766Snetchild ip++; 641158766Snetchild narg--; 642158766Snetchild } else if (ktr->ktr_code == SYS_minherit) { 643158766Snetchild print_number(ip,narg,c); 644158766Snetchild print_number(ip,narg,c); 645158766Snetchild minheritname((int)*ip); 646158766Snetchild ip++; 647158766Snetchild narg--; 648158766Snetchild } else if (ktr->ktr_code == SYS_rfork) { 649158766Snetchild (void)putchar('('); 650158766Snetchild rforkname((int)*ip); 651158766Snetchild ip++; 652158766Snetchild narg--; 653158766Snetchild c = ','; 654158766Snetchild } else if (ktr->ktr_code == SYS_lio_listio) { 655158766Snetchild (void)putchar('('); 656158766Snetchild lio_listioname((int)*ip); 657158766Snetchild ip++; 658158766Snetchild narg--; 659158766Snetchild c = ','; 660158766Snetchild } else if (ktr->ktr_code == SYS_mlockall) { 661158766Snetchild (void)putchar('('); 662158766Snetchild mlockallname((int)*ip); 663158766Snetchild ip++; 664158766Snetchild narg--; 665158766Snetchild } else if (ktr->ktr_code == SYS_sched_setscheduler) { 666158766Snetchild print_number(ip,narg,c); 667158766Snetchild schedpolicyname((int)*ip); 668158766Snetchild ip++; 669158766Snetchild narg--; 670158766Snetchild } else if (ktr->ktr_code == SYS_sched_get_priority_max || 671158766Snetchild ktr->ktr_code == SYS_sched_get_priority_min) { 672158766Snetchild (void)putchar('('); 673158766Snetchild schedpolicyname((int)*ip); 674158766Snetchild ip++; 675158766Snetchild narg--; 676158766Snetchild } else if (ktr->ktr_code == SYS_sendfile) { 677158766Snetchild print_number(ip,narg,c); 678158766Snetchild print_number(ip,narg,c); 679158766Snetchild print_number(ip,narg,c); 680158766Snetchild print_number(ip,narg,c); 681158766Snetchild print_number(ip,narg,c); 682158766Snetchild print_number(ip,narg,c); 683158766Snetchild sendfileflagsname((int)*ip); 684158766Snetchild ip++; 685158766Snetchild narg--; 686158766Snetchild } else if (ktr->ktr_code == SYS_kldsym) { 687158766Snetchild print_number(ip,narg,c); 688158766Snetchild kldsymcmdname((int)*ip); 689158766Snetchild ip++; 690158766Snetchild narg--; 691158766Snetchild } else if (ktr->ktr_code == SYS_sigprocmask) { 692158766Snetchild (void)putchar('('); 693158766Snetchild sigprocmaskhowname((int)*ip); 694158766Snetchild ip++; 695158766Snetchild narg--; 696158766Snetchild c = ','; 697158766Snetchild } else if (ktr->ktr_code == SYS___acl_get_file || 698158766Snetchild ktr->ktr_code == SYS___acl_set_file || 699158766Snetchild ktr->ktr_code == SYS___acl_get_fd || 700158766Snetchild ktr->ktr_code == SYS___acl_set_fd || 701158766Snetchild ktr->ktr_code == SYS___acl_delete_file || 702158766Snetchild ktr->ktr_code == SYS___acl_delete_fd || 703158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_file || 704158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_fd || 705158766Snetchild ktr->ktr_code == SYS___acl_get_link || 706158766Snetchild ktr->ktr_code == SYS___acl_set_link || 707158766Snetchild ktr->ktr_code == SYS___acl_delete_link || 708158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_link) { 709158766Snetchild print_number(ip,narg,c); 710158766Snetchild acltypename((int)*ip); 711158766Snetchild ip++; 712158766Snetchild narg--; 713158766Snetchild } else if (ktr->ktr_code == SYS_sigaction) { 714158766Snetchild (void)putchar('('); 715158766Snetchild signame((int)*ip); 716158766Snetchild ip++; 717158766Snetchild narg--; 718158766Snetchild c = ','; 719158766Snetchild } else if (ktr->ktr_code == SYS_extattrctl) { 720158766Snetchild print_number(ip,narg,c); 721158766Snetchild extattrctlname((int)*ip); 722158766Snetchild ip++; 723158766Snetchild narg--; 724158766Snetchild } else if (ktr->ktr_code == SYS_nmount) { 725158766Snetchild print_number(ip,narg,c); 726158766Snetchild print_number(ip,narg,c); 727158766Snetchild (void)putchar(','); 728158766Snetchild mountflagsname ((int)*ip); 729158766Snetchild ip++; 730158766Snetchild narg--; 731158766Snetchild } else if (ktr->ktr_code == SYS_kse_thr_interrupt) { 732158766Snetchild print_number(ip,narg,c); 733158766Snetchild (void)putchar(','); 734158766Snetchild ksethrcmdname ((int)*ip); 735158766Snetchild ip++; 736158766Snetchild narg--; 737158766Snetchild } else if (ktr->ktr_code == SYS_thr_create) { 738158766Snetchild print_number(ip,narg,c); 739158766Snetchild print_number(ip,narg,c); 740158766Snetchild (void)putchar(','); 741158766Snetchild thrcreateflagsname ((int)*ip); 742158766Snetchild ip++; 743158766Snetchild narg--; 744158766Snetchild } else if (ktr->ktr_code == SYS_thr_kill) { 745158766Snetchild print_number(ip,narg,c); 746158766Snetchild (void)putchar(','); 747158766Snetchild signame ((int)*ip); 748158766Snetchild ip++; 749158766Snetchild narg--; 750158766Snetchild } else if (ktr->ktr_code == SYS_kldunloadf) { 751158766Snetchild print_number(ip,narg,c); 752158766Snetchild (void)putchar(','); 753158766Snetchild kldunloadfflagsname ((int)*ip); 754158766Snetchild ip++; 755158766Snetchild narg--; 7561590Srgrimes } 7571590Srgrimes } 7581590Srgrimes while (narg) { 759158766Snetchild print_number(ip,narg,c); 7601590Srgrimes } 7611590Srgrimes (void)putchar(')'); 7621590Srgrimes } 7631590Srgrimes (void)putchar('\n'); 7641590Srgrimes} 7651590Srgrimes 766100824Sdwmalonevoid 767100824Sdwmalonektrsysret(struct ktr_sysret *ktr) 7681590Srgrimes{ 769100824Sdwmalone register_t ret = ktr->ktr_retval; 770100824Sdwmalone int error = ktr->ktr_error; 771100824Sdwmalone int code = ktr->ktr_code; 7721590Srgrimes 7731590Srgrimes if (code >= nsyscalls || code < 0) 7741590Srgrimes (void)printf("[%d] ", code); 7751590Srgrimes else 7761590Srgrimes (void)printf("%s ", syscallnames[code]); 7771590Srgrimes 7781590Srgrimes if (error == 0) { 7791590Srgrimes if (fancy) { 7801590Srgrimes (void)printf("%d", ret); 7811590Srgrimes if (ret < 0 || ret > 9) 78247957Sdt (void)printf("/%#lx", (long)ret); 7831590Srgrimes } else { 7841590Srgrimes if (decimal) 78547957Sdt (void)printf("%ld", (long)ret); 7861590Srgrimes else 78747957Sdt (void)printf("%#lx", (long)ret); 7881590Srgrimes } 7891590Srgrimes } else if (error == ERESTART) 7901590Srgrimes (void)printf("RESTART"); 7911590Srgrimes else if (error == EJUSTRETURN) 7921590Srgrimes (void)printf("JUSTRETURN"); 7931590Srgrimes else { 7941590Srgrimes (void)printf("-1 errno %d", ktr->ktr_error); 7951590Srgrimes if (fancy) 7961590Srgrimes (void)printf(" %s", strerror(ktr->ktr_error)); 7971590Srgrimes } 7981590Srgrimes (void)putchar('\n'); 7991590Srgrimes} 8001590Srgrimes 801100824Sdwmalonevoid 802100824Sdwmalonektrnamei(char *cp, int len) 8031590Srgrimes{ 8041590Srgrimes (void)printf("\"%.*s\"\n", len, cp); 8051590Srgrimes} 8061590Srgrimes 807100824Sdwmalonevoid 808115759Speterhexdump(char *p, int len, int screenwidth) 8091590Srgrimes{ 810115759Speter int n, i; 811115759Speter int width; 812115759Speter 813115759Speter width = 0; 814115759Speter do { 815115759Speter width += 2; 816115759Speter i = 13; /* base offset */ 817115759Speter i += (width / 2) + 1; /* spaces every second byte */ 818115759Speter i += (width * 2); /* width of bytes */ 819115759Speter i += 3; /* " |" */ 820115759Speter i += width; /* each byte */ 821115759Speter i += 1; /* "|" */ 822115759Speter } while (i < screenwidth); 823115759Speter width -= 2; 824115759Speter 825115759Speter for (n = 0; n < len; n += width) { 826115759Speter for (i = n; i < n + width; i++) { 827115759Speter if ((i % width) == 0) { /* beginning of line */ 828115759Speter printf(" 0x%04x", i); 829115759Speter } 830115759Speter if ((i % 2) == 0) { 831115759Speter printf(" "); 832115759Speter } 833115759Speter if (i < len) 834115759Speter printf("%02x", p[i] & 0xff); 835115759Speter else 836115759Speter printf(" "); 837115759Speter } 838115759Speter printf(" |"); 839115759Speter for (i = n; i < n + width; i++) { 840115759Speter if (i >= len) 841115759Speter break; 842115759Speter if (p[i] >= ' ' && p[i] <= '~') 843115759Speter printf("%c", p[i]); 844115759Speter else 845115759Speter printf("."); 846115759Speter } 847115759Speter printf("|\n"); 848115759Speter } 849115759Speter if ((i % width) != 0) 850115759Speter printf("\n"); 851115759Speter} 852115759Speter 853115759Spetervoid 854115759Spetervisdump(char *dp, int datalen, int screenwidth) 855115759Speter{ 856115759Speter int col = 0; 857100824Sdwmalone char *cp; 858100824Sdwmalone int width; 8591590Srgrimes char visbuf[5]; 8601590Srgrimes 8611590Srgrimes (void)printf(" \""); 8621590Srgrimes col = 8; 8631590Srgrimes for (;datalen > 0; datalen--, dp++) { 8641590Srgrimes (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 8651590Srgrimes cp = visbuf; 8661590Srgrimes /* 8671590Srgrimes * Keep track of printables and 8681590Srgrimes * space chars (like fold(1)). 8691590Srgrimes */ 8701590Srgrimes if (col == 0) { 8711590Srgrimes (void)putchar('\t'); 8721590Srgrimes col = 8; 8731590Srgrimes } 8741590Srgrimes switch(*cp) { 8751590Srgrimes case '\n': 8761590Srgrimes col = 0; 8771590Srgrimes (void)putchar('\n'); 8781590Srgrimes continue; 8791590Srgrimes case '\t': 8801590Srgrimes width = 8 - (col&07); 8811590Srgrimes break; 8821590Srgrimes default: 8831590Srgrimes width = strlen(cp); 8841590Srgrimes } 8851590Srgrimes if (col + width > (screenwidth-2)) { 8861590Srgrimes (void)printf("\\\n\t"); 8871590Srgrimes col = 8; 8881590Srgrimes } 8891590Srgrimes col += width; 8901590Srgrimes do { 8911590Srgrimes (void)putchar(*cp++); 8921590Srgrimes } while (*cp); 8931590Srgrimes } 8941590Srgrimes if (col == 0) 8951590Srgrimes (void)printf(" "); 8961590Srgrimes (void)printf("\"\n"); 8971590Srgrimes} 8981590Srgrimes 899115759Spetervoid 900115759Speterktrgenio(struct ktr_genio *ktr, int len) 901115759Speter{ 902115759Speter int datalen = len - sizeof (struct ktr_genio); 903115759Speter char *dp = (char *)ktr + sizeof (struct ktr_genio); 904115759Speter static int screenwidth = 0; 905115759Speter int i, binary; 906115759Speter 907115759Speter if (screenwidth == 0) { 908115759Speter struct winsize ws; 909115759Speter 910115759Speter if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 911115759Speter ws.ws_col > 8) 912115759Speter screenwidth = ws.ws_col; 913115759Speter else 914115759Speter screenwidth = 80; 915115759Speter } 916115759Speter printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 917115759Speter ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 918115759Speter datalen == 1 ? "" : "s"); 919152331Srwatson if (suppressdata) 920152331Srwatson return; 921115759Speter if (maxdata && datalen > maxdata) 922115759Speter datalen = maxdata; 923115759Speter 924115759Speter for (i = 0, binary = 0; i < datalen && binary == 0; i++) { 925115759Speter if (dp[i] >= 32 && dp[i] < 127) 926115759Speter continue; 927115759Speter if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9) 928115759Speter continue; 929115759Speter binary = 1; 930115759Speter } 931115759Speter if (binary) 932115759Speter hexdump(dp, datalen, screenwidth); 933115759Speter else 934115759Speter visdump(dp, datalen, screenwidth); 935115759Speter} 936115759Speter 937100824Sdwmaloneconst char *signames[] = { 9381590Srgrimes "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 9391590Srgrimes "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 9401590Srgrimes "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 9411590Srgrimes "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 9421590Srgrimes "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 9431590Srgrimes "USR2", NULL, /* 31 - 32 */ 9441590Srgrimes}; 9451590Srgrimes 946100824Sdwmalonevoid 947100824Sdwmalonektrpsig(struct ktr_psig *psig) 9481590Srgrimes{ 949160294Skib if (psig->signo > 0 && psig->signo < NSIG) 950160294Skib (void)printf("SIG%s", signames[psig->signo]); 951160294Skib else 952160294Skib (void)printf("SIG%s ", psig->signo); 9531590Srgrimes if (psig->action == SIG_DFL) 9541590Srgrimes (void)printf("SIG_DFL\n"); 955100824Sdwmalone else { 95647957Sdt (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 957100824Sdwmalone (u_long)psig->action, psig->mask.__bits[0], psig->code); 958100824Sdwmalone } 9591590Srgrimes} 9601590Srgrimes 961100824Sdwmalonevoid 962100824Sdwmalonektrcsw(struct ktr_csw *cs) 9631590Srgrimes{ 9641590Srgrimes (void)printf("%s %s\n", cs->out ? "stop" : "resume", 9651590Srgrimes cs->user ? "user" : "kernel"); 9661590Srgrimes} 9671590Srgrimes 968100824Sdwmalonevoid 969100824Sdwmalonektruser(int len, unsigned char *p) 97018400Sphk{ 97118470Sphk (void)printf("%d ", len); 97218470Sphk while (len--) 973127402Sphk if (decimal) 974127402Sphk (void)printf(" %d", *p++); 975127402Sphk else 976127402Sphk (void)printf(" %02x", *p++); 97718400Sphk (void)printf("\n"); 97818400Sphk 97918400Sphk} 98018400Sphk 981100824Sdwmalonevoid 982100824Sdwmaloneusage(void) 9831590Srgrimes{ 9841590Srgrimes (void)fprintf(stderr, 985152331Srwatson "usage: kdump [-dEnlHRsT] [-f trfile] [-m maxdata] [-p pid] [-t [cnisuw]]\n"); 9861590Srgrimes exit(1); 9871590Srgrimes} 988