Annotation of 43BSDReno/usr.sbin/kgmon/kgmon.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 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) 1983 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[] = "@(#)kgmon.c    5.10 (Berkeley) 6/1/90";
        !            28: #endif /* not lint */
        !            29: 
        !            30: #include <machine/pte.h>
        !            31: 
        !            32: #include <sys/param.h>
        !            33: #include <sys/file.h>
        !            34: #include <sys/vm.h>
        !            35: #include <sys/gprof.h>
        !            36: #include <stdio.h>
        !            37: #include <nlist.h>
        !            38: #include <ctype.h>
        !            39: #include <paths.h>
        !            40: 
        !            41: #define        PROFILING_ON    0
        !            42: #define        PROFILING_OFF   3
        !            43: 
        !            44: u_long s_textsize;
        !            45: off_t  sbuf, klseek(), lseek();
        !            46: int    ssiz;
        !            47: 
        !            48: struct nlist nl[] = {
        !            49: #define        N_SYSMAP        0
        !            50:        { "_Sysmap" },
        !            51: #define        N_SYSSIZE       1
        !            52:        { "_Syssize" },
        !            53: #define N_FROMS                2
        !            54:        { "_froms" },
        !            55: #define        N_PROFILING     3
        !            56:        { "_profiling" },
        !            57: #define        N_S_LOWPC       4
        !            58:        { "_s_lowpc" },
        !            59: #define        N_S_TEXTSIZE    5
        !            60:        { "_s_textsize" },
        !            61: #define        N_SBUF          6
        !            62:        { "_sbuf" },
        !            63: #define N_SSIZ         7
        !            64:        { "_ssiz" },
        !            65: #define        N_TOS           8
        !            66:        { "_tos" },
        !            67:        0,
        !            68: };
        !            69: 
        !            70: struct pte *Sysmap;
        !            71: 
        !            72: int    kmem;
        !            73: int    bflag, hflag, kflag, rflag, pflag;
        !            74: int    debug = 0;
        !            75: 
        !            76: main(argc, argv)
        !            77:        int argc;
        !            78:        char **argv;
        !            79: {
        !            80:        extern char *optarg;
        !            81:        extern int optind;
        !            82:        int ch, mode, disp, openmode;
        !            83:        char *system, *kmemf, *malloc();
        !            84: 
        !            85:        while ((ch = getopt(argc, argv, "bhpr")) != EOF)
        !            86:                switch((char)ch) {
        !            87:                case 'b':
        !            88:                        bflag++;
        !            89:                        break;
        !            90:                case 'h':
        !            91:                        hflag++;
        !            92:                        break;
        !            93:                case 'p':
        !            94:                        pflag++;
        !            95:                        break;
        !            96:                case 'r':
        !            97:                        rflag++;
        !            98:                        break;
        !            99:                default:
        !           100:                        (void)fprintf(stderr,
        !           101:                            "usage: kgmon [-bhrp] [system [core]]\n");
        !           102:                        exit(1);
        !           103:                }
        !           104:        argc -= optind;
        !           105:        argv += optind;
        !           106: 
        !           107:        kmemf = _PATH_KMEM;
        !           108:        if (*argv) {
        !           109:                system = *argv;
        !           110:                if (*++argv) {
        !           111:                        kmemf = *argv;
        !           112:                        ++kflag;
        !           113:                }
        !           114:        }
        !           115:        else
        !           116:                system = _PATH_UNIX;
        !           117: 
        !           118:        if (nlist(system, nl) < 0 || nl[0].n_type == 0) {
        !           119:                (void)fprintf(stderr, "kgmon: %s: no namelist\n", system);
        !           120:                exit(2);
        !           121:        }
        !           122:        if (!nl[N_PROFILING].n_value) {
        !           123:                (void)fprintf(stderr,
        !           124:                    "kgmon: profiling: not defined in kernel.\n");
        !           125:                exit(10);
        !           126:        }
        !           127: 
        !           128:        openmode = (bflag || hflag || pflag || rflag) ? O_RDWR : O_RDONLY;
        !           129:        kmem = open(kmemf, openmode);
        !           130:        if (kmem < 0) {
        !           131:                openmode = O_RDONLY;
        !           132:                kmem = open(kmemf, openmode);
        !           133:                if (kmem < 0) {
        !           134:                        perror(kmemf);
        !           135:                        exit(3);
        !           136:                }
        !           137:                (void)fprintf(stderr, "%s opened read-only\n", kmemf);
        !           138:                if (rflag)
        !           139:                        (void)fprintf(stderr, "-r supressed\n");
        !           140:                if (bflag)
        !           141:                        (void)fprintf(stderr, "-b supressed\n");
        !           142:                if (hflag)
        !           143:                        (void)fprintf(stderr, "-h supressed\n");
        !           144:                rflag = bflag = hflag = 0;
        !           145:        }
        !           146:        if (kflag) {
        !           147:                off_t off;
        !           148: 
        !           149:                Sysmap = (struct pte *)
        !           150:                   malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
        !           151:                if (!Sysmap) {
        !           152:                        (void)fprintf(stderr,
        !           153:                            "kgmon: can't get memory for Sysmap.\n");
        !           154:                        exit(1);
        !           155:                }
        !           156:                off = nl[N_SYSMAP].n_value & ~KERNBASE;
        !           157:                (void)lseek(kmem, off, L_SET);
        !           158:                (void)read(kmem, (char *)Sysmap,
        !           159:                    (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
        !           160:        }
        !           161:        mode = kfetch(N_PROFILING);
        !           162:        if (hflag)
        !           163:                disp = PROFILING_OFF;
        !           164:        else if (bflag)
        !           165:                disp = PROFILING_ON;
        !           166:        else
        !           167:                disp = mode;
        !           168:        if (pflag) {
        !           169:                if (openmode == O_RDONLY && mode == PROFILING_ON)
        !           170:                        (void)fprintf(stderr, "data may be inconsistent\n");
        !           171:                dumpstate();
        !           172:        }
        !           173:        if (rflag)
        !           174:                resetstate();
        !           175:        turnonoff(disp);
        !           176:        (void)fprintf(stdout,
        !           177:            "kernel profiling is %s.\n", disp ? "off" : "running");
        !           178: }
        !           179: 
        !           180: dumpstate()
        !           181: {
        !           182:        extern int errno;
        !           183:        struct rawarc rawarc;
        !           184:        struct tostruct *tos;
        !           185:        u_long frompc;
        !           186:        off_t kfroms, ktos;
        !           187:        u_short *froms;         /* froms is a bunch of u_shorts indexing tos */
        !           188:        int i, fd, fromindex, endfrom, fromssize, tossize, toindex;
        !           189:        char buf[BUFSIZ], *s_lowpc, *malloc(), *strerror();
        !           190: 
        !           191:        turnonoff(PROFILING_OFF);
        !           192:        fd = creat("gmon.out", 0666);
        !           193:        if (fd < 0) {
        !           194:                perror("gmon.out");
        !           195:                return;
        !           196:        }
        !           197:        ssiz = kfetch(N_SSIZ);
        !           198:        sbuf = kfetch(N_SBUF);
        !           199:        (void)klseek(kmem, (off_t)sbuf, L_SET);
        !           200:        for (i = ssiz; i > 0; i -= BUFSIZ) {
        !           201:                read(kmem, buf, i < BUFSIZ ? i : BUFSIZ);
        !           202:                write(fd, buf, i < BUFSIZ ? i : BUFSIZ);
        !           203:        }
        !           204:        s_textsize = kfetch(N_S_TEXTSIZE);
        !           205:        fromssize = s_textsize / HASHFRACTION;
        !           206:        froms = (u_short *)malloc((u_int)fromssize);
        !           207:        kfroms = kfetch(N_FROMS);
        !           208:        (void)klseek(kmem, kfroms, L_SET);
        !           209:        i = read(kmem, ((char *)(froms)), fromssize);
        !           210:        if (i != fromssize) {
        !           211:                (void)fprintf(stderr, "read kmem: request %d, got %d: %s",
        !           212:                    fromssize, i, strerror(errno));
        !           213:                exit(5);
        !           214:        }
        !           215:        tossize = (s_textsize * ARCDENSITY / 100) * sizeof(struct tostruct);
        !           216:        tos = (struct tostruct *)malloc((u_int)tossize);
        !           217:        ktos = kfetch(N_TOS);
        !           218:        (void)klseek(kmem, ktos, L_SET);
        !           219:        i = read(kmem, ((char *)(tos)), tossize);
        !           220:        if (i != tossize) {
        !           221:                (void)fprintf(stderr, "read kmem: request %d, got %d: %s",
        !           222:                    tossize, i, strerror(errno));
        !           223:                exit(6);
        !           224:        }
        !           225:        s_lowpc = (char *)kfetch(N_S_LOWPC);
        !           226:        if (debug)
        !           227:                (void)fprintf(stderr, "s_lowpc 0x%x, s_textsize 0x%x\n",
        !           228:                    s_lowpc, s_textsize);
        !           229:        endfrom = fromssize / sizeof(*froms);
        !           230:        for (fromindex = 0; fromindex < endfrom; fromindex++) {
        !           231:                if (froms[fromindex] == 0)
        !           232:                        continue;
        !           233:                frompc = (u_long)s_lowpc +
        !           234:                    (fromindex * HASHFRACTION * sizeof(*froms));
        !           235:                for (toindex = froms[fromindex]; toindex != 0;
        !           236:                   toindex = tos[toindex].link) {
        !           237:                        if (debug)
        !           238:                            (void)fprintf(stderr,
        !           239:                            "[mcleanup] frompc 0x%x selfpc 0x%x count %d\n" ,
        !           240:                            frompc, tos[toindex].selfpc, tos[toindex].count);
        !           241:                        rawarc.raw_frompc = frompc;
        !           242:                        rawarc.raw_selfpc = (u_long)tos[toindex].selfpc;
        !           243:                        rawarc.raw_count = tos[toindex].count;
        !           244:                        write(fd, (char *)&rawarc, sizeof (rawarc));
        !           245:                }
        !           246:        }
        !           247:        close(fd);
        !           248: }
        !           249: 
        !           250: resetstate()
        !           251: {
        !           252:        off_t kfroms, ktos;
        !           253:        int i, fromssize, tossize;
        !           254:        char buf[BUFSIZ];
        !           255: 
        !           256:        turnonoff(PROFILING_OFF);
        !           257:        bzero(buf, BUFSIZ);
        !           258:        ssiz = kfetch(N_SSIZ);
        !           259:        sbuf = kfetch(N_SBUF);
        !           260:        ssiz -= sizeof(struct phdr);
        !           261:        sbuf += sizeof(struct phdr);
        !           262:        (void)klseek(kmem, (off_t)sbuf, L_SET);
        !           263:        for (i = ssiz; i > 0; i -= BUFSIZ)
        !           264:                if (write(kmem, buf, i < BUFSIZ ? i : BUFSIZ) < 0) {
        !           265:                        perror("sbuf write");
        !           266:                        exit(7);
        !           267:                }
        !           268:        s_textsize = kfetch(N_S_TEXTSIZE);
        !           269:        fromssize = s_textsize / HASHFRACTION;
        !           270:        kfroms = kfetch(N_FROMS);
        !           271:        (void)klseek(kmem, kfroms, L_SET);
        !           272:        for (i = fromssize; i > 0; i -= BUFSIZ)
        !           273:                if (write(kmem, buf, i < BUFSIZ ? i : BUFSIZ) < 0) {
        !           274:                        perror("kforms write");
        !           275:                        exit(8);
        !           276:                }
        !           277:        tossize = (s_textsize * ARCDENSITY / 100) * sizeof(struct tostruct);
        !           278:        ktos = kfetch(N_TOS);
        !           279:        (void)klseek(kmem, ktos, L_SET);
        !           280:        for (i = tossize; i > 0; i -= BUFSIZ)
        !           281:                if (write(kmem, buf, i < BUFSIZ ? i : BUFSIZ) < 0) {
        !           282:                        perror("ktos write");
        !           283:                        exit(9);
        !           284:                }
        !           285: }
        !           286: 
        !           287: turnonoff(onoff)
        !           288:        int onoff;
        !           289: {
        !           290:        (void)klseek(kmem, (long)nl[N_PROFILING].n_value, L_SET);
        !           291:        (void)write(kmem, (char *)&onoff, sizeof (onoff));
        !           292: }
        !           293: 
        !           294: kfetch(index)
        !           295:        int index;
        !           296: {
        !           297:        off_t off;
        !           298:        int value;
        !           299: 
        !           300:        if ((off = nl[index].n_value) == 0) {
        !           301:                printf("%s: not defined in kernel\n", nl[index].n_name);
        !           302:                exit(11);
        !           303:        }
        !           304:        if (klseek(kmem, off, L_SET) == -1) {
        !           305:                perror("lseek");
        !           306:                exit(12);
        !           307:        }
        !           308:        if (read(kmem, (char *)&value, sizeof (value)) != sizeof (value)) {
        !           309:                perror("read");
        !           310:                exit(13);
        !           311:        }
        !           312:        return (value);
        !           313: }
        !           314: 
        !           315: off_t
        !           316: klseek(fd, base, off)
        !           317:        int fd, off;
        !           318:        off_t base;
        !           319: {
        !           320:        if (kflag) {    /* get kernel pte */
        !           321:                base &= ~KERNBASE;
        !           322:                base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
        !           323:        }
        !           324:        return (lseek(fd, base, off));
        !           325: }

unix.superglobalmegacorp.com

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