Annotation of 43BSDReno/usr.bin/ktrace/kdump/kdump.c, revision 1.1.1.1

1.1       root        1: /*-
                      2:  * Copyright (c) 1988 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted provided
                      6:  * that: (1) source distributions retain this entire copyright notice and
                      7:  * comment, and (2) distributions including binaries display the following
                      8:  * acknowledgement:  ``This product includes software developed by the
                      9:  * University of California, Berkeley and its contributors'' in the
                     10:  * documentation or other materials provided with the distribution and in
                     11:  * all advertising materials mentioning features or use of this software.
                     12:  * Neither the name of the University nor the names of its contributors may
                     13:  * be used to endorse or promote products derived from this software without
                     14:  * specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: char copyright[] =
                     22: "@(#) Copyright (c) 1988 The Regents of the University of California.\n\
                     23:  All rights reserved.\n";
                     24: #endif /* not lint */
                     25: 
                     26: #ifndef lint
                     27: static char sccsid[] = "@(#)kdump.c    1.9 (Berkeley) 6/29/90";
                     28: #endif /* not lint */
                     29: 
                     30: #include <sys/ioctl.h>
                     31: #include <vis.h>
                     32: #define KERNEL
                     33: #include <errno.h>
                     34: #undef KERNEL
                     35: #include "ktrace.h"
                     36: 
                     37: int timestamp, decimal, fancy = 1, tail, maxdata;
                     38: char *tracefile = DEF_TRACEFILE;
                     39: struct ktr_header ktr_header;
                     40: int size = 1024;       /* initial size - grow as needed */
                     41: 
                     42: #define USAGE  \
                     43:        "usage: kdump [-dnlT] [-t trops] [-f trfile] [-m maxdata]\n\
                     44:        trops: c = syscalls, n = namei, g = generic-i/o, a = everything\n"
                     45: 
                     46: #define eqs(s1, s2)    (strcmp((s1), (s2)) == 0)
                     47: 
                     48: main(argc, argv)
                     49:        char *argv[];
                     50: {
                     51:        extern int optind;
                     52:        extern char *optarg;
                     53:        int ch, ktrlen;
                     54:        register char *m;
                     55:        int trpoints = ALL_POINTS;
                     56: 
                     57:        while ((ch = getopt(argc,argv,"t:f:dnlTRm:")) != EOF)
                     58:                switch((char)ch) {
                     59:                case 't':
                     60:                        trpoints = getpoints(optarg);
                     61:                        if (trpoints < 0) {
                     62:                                fprintf(stderr, 
                     63:                                     "kdump: unknown trace point in %s\n",
                     64:                                        optarg);
                     65:                                exit(1);
                     66:                        }
                     67:                        break;
                     68:                case 'f':
                     69:                        tracefile = optarg;
                     70:                        break;
                     71:                case 'd':
                     72:                        decimal = 1;
                     73:                        break;
                     74:                case 'n':
                     75:                        fancy = 0;
                     76:                        break;
                     77:                case 'l':
                     78:                        tail = 1;
                     79:                        break;
                     80:                case 'T':
                     81:                        timestamp = 1;
                     82:                        break;
                     83:                case 'R':
                     84:                        timestamp = 2;  /* relative timestamp */
                     85:                        break;
                     86:                case 'm':
                     87:                        maxdata = atoi(optarg);
                     88:                        break;
                     89:                default:
                     90:                        fprintf(stderr, USAGE);
                     91:                        exit(1);
                     92:                }
                     93:        argv += optind, argc -= optind;
                     94: 
                     95:        if (argc > 1) {
                     96:                fprintf(stderr, USAGE);
                     97:                exit(1);
                     98:        }
                     99:        if (!eqs(tracefile, "-")) {
                    100:                if (freopen(tracefile, "r", stdin) == NULL) {
                    101:                        fprintf(stderr, "kdump: %s: ", tracefile);
                    102:                        perror("");
                    103:                        exit(1);
                    104:                }
                    105:        }
                    106:        m = (char *)malloc(size+1);
                    107:        if (m == NULL) {
                    108:                fprintf(stderr, "kdump: ain't gots no memory\n");
                    109:                exit(1);
                    110:        }
                    111:        while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1,
                    112:               stdin, tail)) {
                    113:                if (trpoints & (1<<ktr_header.ktr_type))
                    114:                        dumpheader(&ktr_header);
                    115:                if ((ktrlen = ktr_header.ktr_len) < 0) {
                    116:                        fprintf(stderr, "kdump: bogus length 0x%x\n", 
                    117:                                ktrlen);
                    118:                        exit(1);
                    119:                }
                    120:                if (ktrlen > size) {
                    121:                        m = (char *)realloc(m, ktrlen+1);
                    122:                        if (m == NULL) {
                    123:                                fprintf(stderr,"kdump: out of memory\n");
                    124:                                exit(1);
                    125:                        }
                    126:                        size = ktrlen;
                    127:                }
                    128:                if (ktrlen && fread_tail(m, ktrlen, 1, stdin, tail) == 0) {
                    129:                        fprintf(stderr, "kdump: data too short\n");
                    130:                        exit(1);
                    131:                }
                    132:                if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
                    133:                        continue;
                    134:                switch (ktr_header.ktr_type) {
                    135:                case KTR_SYSCALL:
                    136:                        ktrsyscall((struct ktr_syscall *)m, ktrlen);
                    137:                        break;
                    138:                case KTR_SYSRET:
                    139:                        ktrsysret((struct ktr_sysret *)m, ktrlen);
                    140:                        break;
                    141:                case KTR_NAMEI:
                    142:                        ktrnamei(m, ktrlen);
                    143:                        break;
                    144:                case KTR_GENIO:
                    145:                        ktrgenio((struct ktr_genio *)m, ktrlen);
                    146:                        break;
                    147:                case KTR_PSIG:
                    148:                        ktrpsig((struct ktr_psig *)m, ktrlen);
                    149:                        break;
                    150:                }
                    151:                if (tail)
                    152:                        fflush(stdout);
                    153:        }
                    154: }
                    155: 
                    156: fread_tail(buf, size, num, stream, tail)
                    157:        char *buf;
                    158:        FILE *stream;
                    159: {
                    160:        int i;
                    161: 
                    162:        while ((i = fread(buf, size, num, stream)) == 0 && tail) {
                    163:                sleep(1);
                    164:                clearerr(stream);
                    165:        }
                    166:        return (i);
                    167: }
                    168: 
                    169: dumpheader(kth)
                    170:        struct ktr_header *kth;
                    171: {
                    172:        static char unknown[64];
                    173:        static struct timeval prevtime, temp;
                    174:        char *type;
                    175: 
                    176:        switch (kth->ktr_type) {
                    177:        case KTR_SYSCALL:
                    178:                type = "CALL";
                    179:                break;
                    180:        case KTR_SYSRET:
                    181:                type = "RET ";
                    182:                break;
                    183:        case KTR_NAMEI:
                    184:                type = "NAMI";
                    185:                break;
                    186:        case KTR_GENIO:
                    187:                type = "GIO ";
                    188:                break;
                    189:        case KTR_PSIG:
                    190:                type = "PSIG";
                    191:                break;
                    192:        default:
                    193:                sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
                    194:                type = unknown;
                    195:        }
                    196: 
                    197:        printf("%6d %-8s ",
                    198:                kth->ktr_pid, kth->ktr_comm);
                    199:        if (timestamp) {
                    200:                if (timestamp == 2) {
                    201:                        temp = kth->ktr_time;
                    202:                        timevalsub(&kth->ktr_time, &prevtime);
                    203:                        prevtime = temp;
                    204:                }
                    205:                printf("%d.%06d ", kth->ktr_time.tv_sec, kth->ktr_time.tv_usec);
                    206:        }
                    207:        printf("%s  ", type);
                    208: }
                    209: 
                    210: #include <sys/syscall.h>
                    211: #define KTRACE
                    212: #include "/sys/kern/syscalls.c"
                    213: #undef KTRACE
                    214: int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
                    215: 
                    216: ktrsyscall(ktr, len)
                    217:        register struct ktr_syscall *ktr;
                    218: {
                    219:        register narg = ktr->ktr_narg;
                    220:        register int *ip;
                    221:        char *ioctlname();
                    222: 
                    223:        if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0)
                    224:                printf("[%d]", ktr->ktr_code);
                    225:        else
                    226:                printf("%s", syscallnames[ktr->ktr_code]);
                    227:        ip = (int *)((char *)ktr + sizeof(struct ktr_syscall));
                    228:        if (narg) {
                    229:                char c = '(';
                    230:                if (fancy && ktr->ktr_code == SYS_ioctl) {
                    231:                        char *cp;
                    232:                        if (decimal)
                    233:                                printf("(%d", *ip);
                    234:                        else
                    235:                                printf("(%#x", *ip);
                    236:                        ip++; narg--;
                    237:                        if ((cp = ioctlname(*ip)) != NULL)
                    238:                                printf(",%s", cp);
                    239:                        else {
                    240:                                if (decimal)
                    241:                                        printf(",%d", *ip);
                    242:                                else
                    243:                                        printf(",%#x ", *ip);
                    244:                        }
                    245:                        c = ',';
                    246:                        ip++; narg--;
                    247:                }
                    248:                while (narg) {
                    249:                        if (decimal)
                    250:                                printf("%c%d", c, *ip);
                    251:                        else
                    252:                                printf("%c%#x", c, *ip);
                    253:                        c = ',';
                    254:                        ip++; narg--;
                    255:                }
                    256:                putchar(')');
                    257:        }
                    258:        putchar('\n');
                    259: }
                    260: 
                    261: ktrsysret(ktr, len)
                    262:        struct ktr_sysret *ktr;
                    263: {
                    264:        register int ret = ktr->ktr_retval;
                    265:        register int error = ktr->ktr_error;
                    266:        register int code = ktr->ktr_code;
                    267: 
                    268:        if (code >= nsyscalls || code < 0)
                    269:                printf("[%d] ", code);
                    270:        else
                    271:                printf("%s ", syscallnames[code]);
                    272: 
                    273:        if (error == 0) {
                    274:                if (fancy) {
                    275:                        printf("%d", ret);
                    276:                        if (ret < 0 || ret > 9)
                    277:                                printf("/%#x", ret);
                    278:                } else {
                    279:                        if (decimal)
                    280:                                printf("%d", ret);
                    281:                        else
                    282:                                printf("%#x", ret);
                    283:                }
                    284:        } else if (error == ERESTART)
                    285:                printf("RESTART");
                    286:        else if (error == EJUSTRETURN)
                    287:                printf("JUSTRETURN");
                    288:        else {
                    289:                printf("-1 errno %d", ktr->ktr_error);
                    290:                if (fancy)
                    291:                        printf(" %s", strerror(ktr->ktr_error));
                    292:        }
                    293:        putchar('\n');
                    294: }
                    295: 
                    296: ktrnamei(cp, len) 
                    297:        char *cp;
                    298: {
                    299:        printf("\"%.*s\"\n", len, cp);
                    300: }
                    301: 
                    302: ktrgenio(ktr, len)
                    303:        struct ktr_genio *ktr;
                    304: {
                    305:        register int datalen = len - sizeof (struct ktr_genio);
                    306:        register char *dp = (char *)ktr + sizeof (struct ktr_genio);
                    307:        register char *cp;
                    308:        register int col = 0;
                    309:        register char c;
                    310:        register width;
                    311:        char visbuf[5];
                    312:        static screenwidth = 0;
                    313: 
                    314:        if (screenwidth == 0) {
                    315:                struct winsize ws;
                    316: 
                    317:                if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
                    318:                    ws.ws_col > 8)
                    319:                        screenwidth = ws.ws_col;
                    320:                else
                    321:                        screenwidth = 80;
                    322:        }
                    323:        printf("fd %d %s %d bytes\n", ktr->ktr_fd,
                    324:                ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
                    325:        if (maxdata && datalen > maxdata)
                    326:                datalen = maxdata;
                    327:        printf("       \"");
                    328:        col = 8;
                    329:        for (;datalen > 0; datalen--, dp++) {
                    330:                (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
                    331:                cp = visbuf;
                    332:                /*
                    333:                 * Keep track of printables and
                    334:                 * space chars (like fold(1)).
                    335:                 */
                    336:                if (col == 0) {
                    337:                        putchar('\t');
                    338:                        col = 8;
                    339:                }
                    340:                switch(*cp) {
                    341:                case '\n':
                    342:                        col = 0;
                    343:                        putchar('\n');
                    344:                        continue;
                    345:                case '\t':
                    346:                        width = 8 - (col&07);
                    347:                        break;
                    348:                default:
                    349:                        width = strlen(cp);
                    350:                }
                    351:                if (col + width > (screenwidth-2)) {
                    352:                        printf("\\\n\t");
                    353:                        col = 8;
                    354:                }
                    355:                col += width;
                    356:                do {
                    357:                        putchar(*cp++);
                    358:                } while (*cp);
                    359:        }
                    360:        if (col == 0)
                    361:                printf("       ");
                    362:        printf("\"\n");
                    363: }
                    364: 
                    365: 
                    366: char *signames[] = {
                    367:        "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",     /*  1 - 6  */
                    368:        "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",             /*  7 - 12 */
                    369:        "PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",         /* 13 - 18 */
                    370:        "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",           /* 19 - 24 */
                    371:        "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",        /* 25 - 30 */
                    372:        "USR2", NULL,                                           /* 31 - 32 */
                    373: };
                    374: 
                    375: ktrpsig(psig, len)
                    376:        struct ktr_psig *psig;
                    377: {
                    378:        printf("SIG%s ", signames[psig->signo]);
                    379:        if (psig->action == SIG_DFL)
                    380:                printf("SIG_DFL\n");
                    381:        else {
                    382:                printf("caught handler=0x%x mask=0x%x code=0x%x\n",
                    383:                        psig->action, psig->mask, psig->code);
                    384:        }
                    385: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.