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