[BACK]Return to kdump.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / kdump

Annotation of src/usr.bin/kdump/kdump.c, Revision 1.1

1.1     ! deraadt     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:
        !            34: #ifndef lint
        !            35: static char copyright[] =
        !            36: "@(#) Copyright (c) 1988, 1993\n\
        !            37:        The Regents of the University of California.  All rights reserved.\n";
        !            38: #endif /* not lint */
        !            39:
        !            40: #ifndef lint
        !            41: #if 0
        !            42: static char sccsid[] = "@(#)kdump.c    8.4 (Berkeley) 4/28/95";
        !            43: #endif
        !            44: static char *rcsid = "$NetBSD: kdump.c,v 1.12 1995/08/31 23:18:33 jtc Exp $";
        !            45: #endif /* not lint */
        !            46:
        !            47: #include <sys/param.h>
        !            48: #include <sys/errno.h>
        !            49: #include <sys/time.h>
        !            50: #include <sys/uio.h>
        !            51: #include <sys/ktrace.h>
        !            52: #include <sys/ioctl.h>
        !            53: #include <sys/ptrace.h>
        !            54: #define _KERNEL
        !            55: #include <sys/errno.h>
        !            56: #undef _KERNEL
        !            57:
        !            58: #include <err.h>
        !            59: #include <signal.h>
        !            60: #include <stdio.h>
        !            61: #include <stdlib.h>
        !            62: #include <string.h>
        !            63: #include <unistd.h>
        !            64: #include <vis.h>
        !            65:
        !            66: #include "ktrace.h"
        !            67:
        !            68: int timestamp, decimal, fancy = 1, tail, maxdata;
        !            69: char *tracefile = DEF_TRACEFILE;
        !            70: struct ktr_header ktr_header;
        !            71:
        !            72: #define eqs(s1, s2)    (strcmp((s1), (s2)) == 0)
        !            73:
        !            74: #include <sys/syscall.h>
        !            75:
        !            76: #include "../../sys/compat/hpux/hpux_syscall.h"
        !            77: #include "../../sys/compat/ibcs2/ibcs2_syscall.h"
        !            78: #include "../../sys/compat/linux/linux_syscall.h"
        !            79: #include "../../sys/compat/osf1/osf1_syscall.h"
        !            80: #include "../../sys/compat/sunos/sunos_syscall.h"
        !            81: #include "../../sys/compat/svr4/svr4_syscall.h"
        !            82: #include "../../sys/compat/ultrix/ultrix_syscall.h"
        !            83:
        !            84: #define KTRACE
        !            85: #include "../../sys/kern/syscalls.c"
        !            86:
        !            87: #include "../../sys/compat/hpux/hpux_syscalls.c"
        !            88: #include "../../sys/compat/ibcs2/ibcs2_syscalls.c"
        !            89: #include "../../sys/compat/linux/linux_syscalls.c"
        !            90: #include "../../sys/compat/osf1/osf1_syscalls.c"
        !            91: #include "../../sys/compat/sunos/sunos_syscalls.c"
        !            92: #include "../../sys/compat/svr4/svr4_syscalls.c"
        !            93: #include "../../sys/compat/ultrix/ultrix_syscalls.c"
        !            94: #undef KTRACE
        !            95:
        !            96: struct emulation {
        !            97:        char *name;             /* Emulation name */
        !            98:        char **sysnames;        /* Array of system call names */
        !            99:        int  nsysnames;         /* Number of */
        !           100: };
        !           101:
        !           102: static struct emulation emulations[] = {
        !           103:        { "netbsd",          syscallnames,        SYS_MAXSYSCALL },
        !           104:        { "hpux",       hpux_syscallnames,   HPUX_SYS_MAXSYSCALL },
        !           105:        { "ibcs2",     ibcs2_syscallnames,  IBCS2_SYS_MAXSYSCALL },
        !           106:        { "linux",     linux_syscallnames,  LINUX_SYS_MAXSYSCALL },
        !           107:        { "osf1",       osf1_syscallnames,   OSF1_SYS_MAXSYSCALL },
        !           108:        { "sunos",     sunos_syscallnames,  SUNOS_SYS_MAXSYSCALL },
        !           109:        { "svr4",       svr4_syscallnames,   SVR4_SYS_MAXSYSCALL },
        !           110:        { "ultrix",   ultrix_syscallnames, ULTRIX_SYS_MAXSYSCALL },
        !           111:        { NULL,                      NULL,                  NULL }
        !           112: };
        !           113:
        !           114: struct emulation *current;
        !           115:
        !           116:
        !           117: static char *ptrace_ops[] = {
        !           118:        "PT_TRACE_ME",  "PT_READ_I",    "PT_READ_D",    "PT_READ_U",
        !           119:        "PT_WRITE_I",   "PT_WRITE_D",   "PT_WRITE_U",   "PT_CONTINUE",
        !           120:        "PT_KILL",      "PT_ATTACH",    "PT_DETACH",
        !           121: };
        !           122:
        !           123: int
        !           124: main(argc, argv)
        !           125:        int argc;
        !           126:        char *argv[];
        !           127: {
        !           128:        int ch, ktrlen, size;
        !           129:        register void *m;
        !           130:        int trpoints = ALL_POINTS;
        !           131:
        !           132:        current = &emulations[0];       /* NetBSD */
        !           133:
        !           134:        while ((ch = getopt(argc, argv, "e:f:dlm:nRTt:")) != -1)
        !           135:                switch (ch) {
        !           136:                case 'e':
        !           137:                        setemul(optarg);
        !           138:                        break;
        !           139:                case 'f':
        !           140:                        tracefile = optarg;
        !           141:                        break;
        !           142:                case 'd':
        !           143:                        decimal = 1;
        !           144:                        break;
        !           145:                case 'l':
        !           146:                        tail = 1;
        !           147:                        break;
        !           148:                case 'm':
        !           149:                        maxdata = atoi(optarg);
        !           150:                        break;
        !           151:                case 'n':
        !           152:                        fancy = 0;
        !           153:                        break;
        !           154:                case 'R':
        !           155:                        timestamp = 2;  /* relative timestamp */
        !           156:                        break;
        !           157:                case 'T':
        !           158:                        timestamp = 1;
        !           159:                        break;
        !           160:                case 't':
        !           161:                        trpoints = getpoints(optarg);
        !           162:                        if (trpoints < 0)
        !           163:                                errx(1, "unknown trace point in %s", optarg);
        !           164:                        break;
        !           165:                default:
        !           166:                        usage();
        !           167:                }
        !           168:        argv += optind;
        !           169:        argc -= optind;
        !           170:
        !           171:        if (argc > 1)
        !           172:                usage();
        !           173:
        !           174:        m = (void *)malloc(size = 1025);
        !           175:        if (m == NULL)
        !           176:                errx(1, "%s", strerror(ENOMEM));
        !           177:        if (!freopen(tracefile, "r", stdin))
        !           178:                err(1, "%s", tracefile);
        !           179:        while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
        !           180:                if (trpoints & (1<<ktr_header.ktr_type))
        !           181:                        dumpheader(&ktr_header);
        !           182:                if ((ktrlen = ktr_header.ktr_len) < 0)
        !           183:                        errx(1, "bogus length 0x%x", ktrlen);
        !           184:                if (ktrlen > size) {
        !           185:                        m = (void *)realloc(m, ktrlen+1);
        !           186:                        if (m == NULL)
        !           187:                                errx(1, "%s", strerror(ENOMEM));
        !           188:                        size = ktrlen;
        !           189:                }
        !           190:                if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
        !           191:                        errx(1, "data too short");
        !           192:                if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
        !           193:                        continue;
        !           194:                switch (ktr_header.ktr_type) {
        !           195:                case KTR_SYSCALL:
        !           196:                        ktrsyscall((struct ktr_syscall *)m);
        !           197:                        break;
        !           198:                case KTR_SYSRET:
        !           199:                        ktrsysret((struct ktr_sysret *)m);
        !           200:                        break;
        !           201:                case KTR_NAMEI:
        !           202:                        ktrnamei(m, ktrlen);
        !           203:                        break;
        !           204:                case KTR_GENIO:
        !           205:                        ktrgenio((struct ktr_genio *)m, ktrlen);
        !           206:                        break;
        !           207:                case KTR_PSIG:
        !           208:                        ktrpsig((struct ktr_psig *)m);
        !           209:                        break;
        !           210:                case KTR_CSW:
        !           211:                        ktrcsw((struct ktr_csw *)m);
        !           212:                        break;
        !           213:                case KTR_EMUL:
        !           214:                        ktremul(m, ktrlen);
        !           215:                        break;
        !           216:                }
        !           217:                if (tail)
        !           218:                        (void)fflush(stdout);
        !           219:        }
        !           220: }
        !           221:
        !           222: fread_tail(buf, size, num)
        !           223:        char *buf;
        !           224:        int num, size;
        !           225: {
        !           226:        int i;
        !           227:
        !           228:        while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
        !           229:                (void)sleep(1);
        !           230:                clearerr(stdin);
        !           231:        }
        !           232:        return (i);
        !           233: }
        !           234:
        !           235: dumpheader(kth)
        !           236:        struct ktr_header *kth;
        !           237: {
        !           238:        char unknown[64], *type;
        !           239:        static struct timeval prevtime;
        !           240:        struct timeval temp;
        !           241:
        !           242:        switch (kth->ktr_type) {
        !           243:        case KTR_SYSCALL:
        !           244:                type = "CALL";
        !           245:                break;
        !           246:        case KTR_SYSRET:
        !           247:                type = "RET ";
        !           248:                break;
        !           249:        case KTR_NAMEI:
        !           250:                type = "NAMI";
        !           251:                break;
        !           252:        case KTR_GENIO:
        !           253:                type = "GIO ";
        !           254:                break;
        !           255:        case KTR_PSIG:
        !           256:                type = "PSIG";
        !           257:                break;
        !           258:        case KTR_CSW:
        !           259:                type = "CSW";
        !           260:                break;
        !           261:        case KTR_EMUL:
        !           262:                type = "EMUL";
        !           263:                break;
        !           264:        default:
        !           265:                (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
        !           266:                type = unknown;
        !           267:        }
        !           268:
        !           269:        (void)printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN, kth->ktr_comm);
        !           270:        if (timestamp) {
        !           271:                if (timestamp == 2) {
        !           272:                        timersub(&kth->ktr_time, &prevtime, &temp);
        !           273:                        prevtime = kth->ktr_time;
        !           274:                } else
        !           275:                        temp = kth->ktr_time;
        !           276:                (void)printf("%ld.%06ld ", temp.tv_sec, temp.tv_usec);
        !           277:        }
        !           278:        (void)printf("%s  ", type);
        !           279: }
        !           280:
        !           281:
        !           282: ktrsyscall(ktr)
        !           283:        register struct ktr_syscall *ktr;
        !           284: {
        !           285:        register argsize = ktr->ktr_argsize;
        !           286:        register register_t *ap;
        !           287:        char *ioctlname();
        !           288:
        !           289:        if (ktr->ktr_code >= current->nsysnames || ktr->ktr_code < 0)
        !           290:                (void)printf("[%d]", ktr->ktr_code);
        !           291:        else
        !           292:                (void)printf("%s", current->sysnames[ktr->ktr_code]);
        !           293:        ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall));
        !           294:        if (argsize) {
        !           295:                char c = '(';
        !           296:                if (fancy) {
        !           297:                        if (ktr->ktr_code == SYS_ioctl) {
        !           298:                                char *cp;
        !           299:                                if (decimal)
        !           300:                                        (void)printf("(%ld", (long)*ap);
        !           301:                                else
        !           302:                                        (void)printf("(%#lx", (long)*ap);
        !           303:                                ap++;
        !           304:                                argsize -= sizeof(register_t);
        !           305:                                if ((cp = ioctlname(*ap)) != NULL)
        !           306:                                        (void)printf(",%s", cp);
        !           307:                                else {
        !           308:                                        if (decimal)
        !           309:                                                (void)printf(",%ld",
        !           310:                                                    (long)*ap);
        !           311:                                        else
        !           312:                                                (void)printf(",%#lx ",
        !           313:                                                    (long)*ap);
        !           314:                                }
        !           315:                                c = ',';
        !           316:                                ap++;
        !           317:                                argsize -= sizeof(register_t);
        !           318:                        } else if (ktr->ktr_code == SYS_ptrace) {
        !           319:                                if (*ap >= 0 && *ap <=
        !           320:                                    sizeof(ptrace_ops) / sizeof(ptrace_ops[0]))
        !           321:                                        (void)printf("(%s", ptrace_ops[*ap]);
        !           322:                                else
        !           323:                                        (void)printf("(%ld", (long)*ap);
        !           324:                                c = ',';
        !           325:                                ap++;
        !           326:                                argsize -= sizeof(register_t);
        !           327:                        }
        !           328:                }
        !           329:                while (argsize) {
        !           330:                        if (decimal)
        !           331:                                (void)printf("%c%ld", c, (long)*ap);
        !           332:                        else
        !           333:                                (void)printf("%c%#lx", c, (long)*ap);
        !           334:                        c = ',';
        !           335:                        ap++;
        !           336:                        argsize -= sizeof(register_t);
        !           337:                }
        !           338:                (void)putchar(')');
        !           339:        }
        !           340:        (void)putchar('\n');
        !           341: }
        !           342:
        !           343: ktrsysret(ktr)
        !           344:        struct ktr_sysret *ktr;
        !           345: {
        !           346:        register int ret = ktr->ktr_retval;
        !           347:        register int error = ktr->ktr_error;
        !           348:        register int code = ktr->ktr_code;
        !           349:
        !           350:        if (code >= current->nsysnames || code < 0)
        !           351:                (void)printf("[%d] ", code);
        !           352:        else
        !           353:                (void)printf("%s ", current->sysnames[code]);
        !           354:
        !           355:        if (error == 0) {
        !           356:                if (fancy) {
        !           357:                        (void)printf("%d", ret);
        !           358:                        if (ret < 0 || ret > 9)
        !           359:                                (void)printf("/%#x", ret);
        !           360:                } else {
        !           361:                        if (decimal)
        !           362:                                (void)printf("%d", ret);
        !           363:                        else
        !           364:                                (void)printf("%#x", ret);
        !           365:                }
        !           366:        } else if (error == ERESTART)
        !           367:                (void)printf("RESTART");
        !           368:        else if (error == EJUSTRETURN)
        !           369:                (void)printf("JUSTRETURN");
        !           370:        else {
        !           371:                (void)printf("-1 errno %d", ktr->ktr_error);
        !           372:                if (fancy)
        !           373:                        (void)printf(" %s", strerror(ktr->ktr_error));
        !           374:        }
        !           375:        (void)putchar('\n');
        !           376: }
        !           377:
        !           378: ktrnamei(cp, len)
        !           379:        char *cp;
        !           380: {
        !           381:        (void)printf("\"%.*s\"\n", len, cp);
        !           382: }
        !           383:
        !           384: ktremul(cp, len)
        !           385:        char *cp;
        !           386: {
        !           387:        char name[1024];
        !           388:
        !           389:        if (len >= sizeof(name))
        !           390:                errx(1, "Emulation name too long");
        !           391:
        !           392:        strncpy(name, cp, len);
        !           393:        name[len] = '\0';
        !           394:        (void)printf("\"%s\"\n", name);
        !           395:
        !           396:        setemul(name);
        !           397: }
        !           398:
        !           399: ktrgenio(ktr, len)
        !           400:        struct ktr_genio *ktr;
        !           401: {
        !           402:        register int datalen = len - sizeof (struct ktr_genio);
        !           403:        register char *dp = (char *)ktr + sizeof (struct ktr_genio);
        !           404:        register char *cp;
        !           405:        register int col = 0;
        !           406:        register width;
        !           407:        char visbuf[5];
        !           408:        static screenwidth = 0;
        !           409:
        !           410:        if (screenwidth == 0) {
        !           411:                struct winsize ws;
        !           412:
        !           413:                if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
        !           414:                    ws.ws_col > 8)
        !           415:                        screenwidth = ws.ws_col;
        !           416:                else
        !           417:                        screenwidth = 80;
        !           418:        }
        !           419:        printf("fd %d %s %d bytes\n", ktr->ktr_fd,
        !           420:                ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
        !           421:        if (maxdata && datalen > maxdata)
        !           422:                datalen = maxdata;
        !           423:        (void)printf("       \"");
        !           424:        col = 8;
        !           425:        for (; datalen > 0; datalen--, dp++) {
        !           426:                (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
        !           427:                cp = visbuf;
        !           428:                /*
        !           429:                 * Keep track of printables and
        !           430:                 * space chars (like fold(1)).
        !           431:                 */
        !           432:                if (col == 0) {
        !           433:                        (void)putchar('\t');
        !           434:                        col = 8;
        !           435:                }
        !           436:                switch(*cp) {
        !           437:                case '\n':
        !           438:                        col = 0;
        !           439:                        (void)putchar('\n');
        !           440:                        continue;
        !           441:                case '\t':
        !           442:                        width = 8 - (col&07);
        !           443:                        break;
        !           444:                default:
        !           445:                        width = strlen(cp);
        !           446:                }
        !           447:                if (col + width > (screenwidth-2)) {
        !           448:                        (void)printf("\\\n\t");
        !           449:                        col = 8;
        !           450:                }
        !           451:                col += width;
        !           452:                do {
        !           453:                        (void)putchar(*cp++);
        !           454:                } while (*cp);
        !           455:        }
        !           456:        if (col == 0)
        !           457:                (void)printf("       ");
        !           458:        (void)printf("\"\n");
        !           459: }
        !           460:
        !           461: ktrpsig(psig)
        !           462:        struct ktr_psig *psig;
        !           463: {
        !           464:        (void)printf("SIG%s ", sys_signame[psig->signo]);
        !           465:        if (psig->action == SIG_DFL)
        !           466:                (void)printf("SIG_DFL\n");
        !           467:        else
        !           468:                (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n",
        !           469:                    (u_long)psig->action, psig->mask, psig->code);
        !           470: }
        !           471:
        !           472: ktrcsw(cs)
        !           473:        struct ktr_csw *cs;
        !           474: {
        !           475:        (void)printf("%s %s\n", cs->out ? "stop" : "resume",
        !           476:            cs->user ? "user" : "kernel");
        !           477: }
        !           478:
        !           479: usage()
        !           480: {
        !           481:
        !           482:        (void)fprintf(stderr,
        !           483: "usage: kdump [-dnlRT] [-e emulation] [-f trfile] [-m maxdata] [-t [cnis]]\n");
        !           484:        exit(1);
        !           485: }
        !           486:
        !           487: setemul(name)
        !           488:        char *name;
        !           489: {
        !           490:        int i;
        !           491:        for (i = 0; emulations[i].name != NULL; i++)
        !           492:                if (strcmp(emulations[i].name, name) == 0) {
        !           493:                        current = &emulations[i];
        !           494:                        return;
        !           495:                }
        !           496:        warnx("Emulation `%s' unknown", name);
        !           497: }