|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: char copyright[] = ! 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)analyze.c 5.2 (Berkeley) 5/14/86"; ! 15: #endif not lint ! 16: ! 17: /* ! 18: * Analyze - analyze a core (and optional paging area) saved from ! 19: * a virtual Unix system crash. ! 20: */ ! 21: #include <stdio.h> ! 22: #include <sys/param.h> ! 23: #include <sys/dir.h> ! 24: #include <machine/pte.h> ! 25: #include <nlist.h> ! 26: #include <sys/map.h> ! 27: #include <sys/user.h> ! 28: #include <sys/proc.h> ! 29: #include <sys/text.h> ! 30: #include <sys/cmap.h> ! 31: #include <sys/vm.h> ! 32: ! 33: int Dflg; ! 34: int dflg; ! 35: int vflg; ! 36: int mflg; ! 37: int fflg; ! 38: int sflg; ! 39: int uflg; ! 40: ! 41: /* use vprintf with care; it plays havoc with ``else's'' */ ! 42: #define vprintf if (vflg) printf ! 43: ! 44: #ifdef vax ! 45: #define clear(x) ((int)x & 0x7fffffff) ! 46: #else ! 47: #define clear(x) ((int)x) ! 48: #endif ! 49: ! 50: struct proc *proc, *aproc; ! 51: int nproc; ! 52: struct text *text, *atext; ! 53: int ntext; ! 54: struct mapent *swapmap; ! 55: int nswapmap; ! 56: int dmmin, dmmax, dmtext; ! 57: struct cmap *cmap; ! 58: int ecmx; ! 59: struct pte *usrpt; ! 60: struct pte *Usrptma; ! 61: int firstfree; ! 62: int maxfree; ! 63: int freemem; ! 64: struct pte p0br[ctopt(btoc(MAXTSIZ+MAXDSIZ+MAXSSIZ))][NPTEPG]; ! 65: int pid; ! 66: ! 67: struct paginfo { ! 68: char z_type; ! 69: char z_count; ! 70: short z_pid; ! 71: struct pte z_pte; ! 72: } *paginfo; ! 73: #define ZLOST 0 ! 74: #define ZDATA 1 ! 75: #define ZSTACK 2 ! 76: #define ZUDOT 3 ! 77: #define ZPAGET 4 ! 78: #define ZTEXT 5 ! 79: #define ZFREE 6 ! 80: #define ZINTRAN 7 ! 81: ! 82: struct dblks { ! 83: short d_first; ! 84: short d_size; ! 85: char d_type; ! 86: char d_index; ! 87: } *dblks; ! 88: int ndblks; ! 89: ! 90: #define DFREE 0 ! 91: #define DDATA 1 ! 92: #define DSTACK 2 ! 93: #define DTEXT 3 ! 94: #define DUDOT 4 ! 95: #define DPAGET 5 ! 96: ! 97: union { ! 98: char buf[UPAGES][NBPG]; ! 99: struct user U; ! 100: } u_area; ! 101: #define u u_area.U ! 102: ! 103: int fcore = -1; ! 104: int fswap = -1; ! 105: ! 106: struct nlist nl[] = { ! 107: #define X_PROC 0 ! 108: { "_proc" }, ! 109: #define X_USRPT 1 ! 110: { "_usrpt" }, ! 111: #define X_PTMA 2 ! 112: { "_Usrptmap" }, ! 113: #define X_FIRSTFREE 3 ! 114: { "_firstfree" }, ! 115: #define X_MAXFREE 4 ! 116: { "_maxfree" }, ! 117: #define X_TEXT 5 ! 118: { "_text" }, ! 119: #define X_FREEMEM 6 ! 120: { "_freemem" }, ! 121: #define X_CMAP 7 ! 122: { "_cmap" }, ! 123: #define X_ECMAP 8 ! 124: { "_ecmap" }, ! 125: #define X_SWAPMAP 9 ! 126: { "_swapmap" }, ! 127: #define X_NPROC 10 ! 128: { "_nproc" }, ! 129: #define X_NTEXT 11 ! 130: { "_ntext" }, ! 131: #define X_NSWAPMAP 12 ! 132: { "_nswapmap" }, ! 133: #define X_DMMIN 13 ! 134: { "_dmmin" }, ! 135: #define X_DMMAX 14 ! 136: { "_dmmax" }, ! 137: #define X_DMTEXT 15 ! 138: { "_dmtext" }, ! 139: { "" } ! 140: }; ! 141: ! 142: main(argc, argv) ! 143: int argc; ! 144: char **argv; ! 145: { ! 146: register struct nlist *np; ! 147: register struct proc *p; ! 148: register struct text *xp; ! 149: register struct pte *pte; ! 150: register int i; ! 151: int w, a; ! 152: ! 153: #ifdef DEBUG ! 154: setbuf(stdout, NULL); ! 155: #endif ! 156: argc--, argv++; ! 157: while (argc > 0 && argv[0][0] == '-') { ! 158: register char *cp = *argv++; ! 159: argc--; ! 160: while (*++cp) switch (*cp) { ! 161: ! 162: case 'm': ! 163: mflg++; ! 164: break; ! 165: ! 166: case 'v': ! 167: vflg++; ! 168: break; ! 169: ! 170: case 's': ! 171: if (argc < 2) ! 172: goto usage; ! 173: if ((fswap = open(argv[0], 0)) < 0) { ! 174: perror(argv[0]); ! 175: exit(1); ! 176: } ! 177: argc--,argv++; ! 178: sflg++; ! 179: break; ! 180: ! 181: case 'f': ! 182: fflg++; ! 183: break; ! 184: ! 185: case 'D': ! 186: Dflg++; ! 187: break; ! 188: ! 189: case 'd': ! 190: dflg++; ! 191: break; ! 192: ! 193: case 'u': ! 194: uflg++; ! 195: break; ! 196: ! 197: default: ! 198: goto usage; ! 199: } ! 200: } ! 201: if (argc < 1) { ! 202: usage: ! 203: fprintf(stderr, "usage: analyze [ -vmfd ] [ -s swapfile ] corefile [ system ]\n"); ! 204: exit(1); ! 205: } ! 206: close(0); ! 207: if ((fcore = open(argv[0], 0)) < 0) { ! 208: perror(argv[0]); ! 209: exit(1); ! 210: } ! 211: nlist(argc > 1 ? argv[1] : "/vmunix", nl); ! 212: if (nl[0].n_value == 0) { ! 213: fprintf(stderr, "%s: bad namelist\n", ! 214: argc > 1 ? argv[1] : "/vmunix"); ! 215: exit(1); ! 216: } ! 217: for (np = nl; np->n_name && *np->n_name; np++) ! 218: vprintf("%8.8s %x\n", np->n_name ,np->n_value ); ! 219: usrpt = (struct pte *)clear(nl[X_USRPT].n_value); ! 220: Usrptma = (struct pte *)clear(nl[X_PTMA].n_value); ! 221: firstfree = get(nl[X_FIRSTFREE].n_value); ! 222: maxfree = get(nl[X_MAXFREE].n_value); ! 223: freemem = get(nl[X_FREEMEM].n_value); ! 224: dmmin = get(nl[X_DMMIN]); ! 225: dmmax = get(nl[X_DMMAX]); ! 226: dmtext = get(nl[X_DMTEXT]); ! 227: paginfo = (struct paginfo *)calloc(maxfree, sizeof (struct paginfo)); ! 228: if (paginfo == NULL) { ! 229: fprintf(stderr, "maxfree %x?... out of mem!\n", maxfree); ! 230: exit(1); ! 231: } ! 232: vprintf("usrpt %x\nUsrptma %x\nfirstfree %x\nmaxfree %x\nfreemem %x\n", ! 233: usrpt, Usrptma, firstfree, maxfree, freemem); ! 234: { ! 235: lseek(fcore, (long)clear(nl[X_PROC].n_value), 0); ! 236: read(fcore, (char *)&aproc, sizeof aproc); ! 237: lseek(fcore, (long)clear(nl[X_NPROC].n_value), 0); ! 238: read(fcore, (char *)&nproc, sizeof nproc); ! 239: printf("%d procs\n", nproc); ! 240: proc = (struct proc *)calloc(nproc, sizeof (struct proc)); ! 241: lseek(fcore, (long)clear(aproc), 0); ! 242: if (read(fcore, (char *)proc, nproc * sizeof (struct proc)) ! 243: != nproc * sizeof (struct proc)) { ! 244: perror("proc read"); ! 245: exit(1); ! 246: } ! 247: } ! 248: { ! 249: lseek(fcore, (long)clear(nl[X_TEXT].n_value), 0); ! 250: read(fcore, (char *)&atext, sizeof atext); ! 251: lseek(fcore, (long)clear(nl[X_NTEXT].n_value), 0); ! 252: read(fcore, (char *)&ntext, sizeof ntext); ! 253: printf("%d texts\n", ntext); ! 254: text = (struct text *)calloc(ntext, sizeof (struct text)); ! 255: lseek(fcore, (long)clear(atext), 0); ! 256: if (read(fcore, (char *)text, ntext * sizeof (struct text)) ! 257: != ntext * sizeof (struct text)) { ! 258: perror("text read"); ! 259: exit(1); ! 260: } ! 261: } ! 262: i = (get(nl[X_ECMAP].n_value) - get(nl[X_CMAP].n_value)); ! 263: ecmx = i / sizeof (struct cmap); ! 264: cmap = (struct cmap *)calloc(i, 1); ! 265: if (cmap == NULL) { ! 266: fprintf(stderr, "not enough mem for %x bytes of cmap\n", i); ! 267: exit(1); ! 268: } ! 269: lseek(fcore, (long)clear(get(nl[X_CMAP].n_value)), 0); ! 270: if (read(fcore, (char *)cmap, i) != i) { ! 271: perror("cmap read"); ! 272: exit(1); ! 273: } ! 274: { struct mapent *aswapmap; ! 275: lseek(fcore, (long)clear(nl[X_SWAPMAP].n_value), 0); ! 276: read(fcore, (char *)&aswapmap, sizeof aswapmap); ! 277: lseek(fcore, (long)clear(nl[X_NSWAPMAP].n_value), 0); ! 278: read(fcore, (char *)&nswapmap, sizeof nswapmap); ! 279: nswapmap--; ! 280: printf("%d swapmap entries\n", nswapmap); ! 281: swapmap = (struct mapent *)calloc(nswapmap, sizeof (struct mapent)); ! 282: dblks = (struct dblks *)calloc(2 * nswapmap, sizeof (struct dblks)); ! 283: lseek(fcore, (long)clear(aswapmap+1), 0); ! 284: if (read(fcore, (char *)swapmap, nswapmap * sizeof (struct mapent)) ! 285: != nswapmap * sizeof (struct mapent)) { ! 286: perror("swapmap read"); ! 287: exit(1); ! 288: } ! 289: } ! 290: for (p = &proc[1]; p < proc+nproc; p++) { ! 291: p->p_p0br = (struct pte *)clear(p->p_p0br); ! 292: p->p_addr = (struct pte *)clear(p->p_addr); ! 293: if (p->p_stat == 0) ! 294: continue; ! 295: printf("proc %d ", p->p_pid); ! 296: if (p->p_stat == SZOMB) { ! 297: printf("zombie\n"); ! 298: continue; ! 299: } ! 300: if (p->p_flag & SLOAD) { ! 301: printf("loaded, p0br %x, ", p->p_p0br); ! 302: printf("%d pages of page tables:", p->p_szpt); ! 303: a = btokmx(p->p_p0br); ! 304: for (i = 0; i < p->p_szpt; i++) { ! 305: w = get(&Usrptma[a + i]); ! 306: printf(" %x", w & PG_PFNUM); ! 307: } ! 308: printf("\n"); ! 309: for(i = 0; i < p->p_szpt; i++) { ! 310: w = get(&Usrptma[a + i]); ! 311: if (getpt(w, i)) ! 312: count(p, (struct pte *)&w, ZPAGET); ! 313: } ! 314: } else { ! 315: /* i = ctopt(btoc(u.u_exdata.ux_dsize)); */ ! 316: i = clrnd(ctopt(p->p_tsize + p->p_dsize + p->p_ssize)); ! 317: printf("swapped, swaddr %x\n", p->p_swaddr); ! 318: duse(p->p_swaddr, ctod(clrnd(UPAGES)), DUDOT, p - proc); ! 319: duse(p->p_swaddr + ctod(UPAGES), ! 320: ctod(clrnd(i - p->p_tsize / NPTEPG)), ! 321: DPAGET, p - proc); ! 322: /* i, DPAGET, p - proc); */ ! 323: } ! 324: p->p_p0br = (struct pte *)p0br; ! 325: p->p_addr = uaddr(p); ! 326: if (p->p_textp) ! 327: p->p_textp = &text[p->p_textp - atext]; ! 328: if (p->p_pid == 2) ! 329: continue; ! 330: if (getu(p)) ! 331: continue; ! 332: u.u_procp = p; ! 333: pdmap(); ! 334: if ((p->p_flag & SLOAD) == 0) ! 335: continue; ! 336: pid = p->p_pid; ! 337: for (i = 0; i < p->p_tsize; i++) { ! 338: pte = tptopte(p, i); ! 339: if (pte->pg_fod || pte->pg_pfnum == 0) ! 340: continue; ! 341: if (pte->pg_pfnum >= firstfree && pte->pg_pfnum < maxfree && cmap[pgtocm(pte->pg_pfnum)].c_intrans) ! 342: count(p, pte, ZINTRAN); ! 343: else ! 344: count(p, pte, ZTEXT); ! 345: } ! 346: vprintf("\n"); ! 347: for (i = 0; i < p->p_dsize; i++) { ! 348: pte = dptopte(p, i); ! 349: if (pte->pg_fod || pte->pg_pfnum == 0) ! 350: continue; ! 351: if (pte->pg_pfnum >= firstfree && pte->pg_pfnum < maxfree && cmap[pgtocm(pte->pg_pfnum)].c_intrans) ! 352: count(p, pte, ZINTRAN); ! 353: else ! 354: count(p, pte, ZDATA); ! 355: } ! 356: vprintf("\n"); ! 357: for (i = 0; i < p->p_ssize; i++) { ! 358: pte = sptopte(p, i); ! 359: if (pte->pg_fod || pte->pg_pfnum == 0) ! 360: continue; ! 361: if (pte->pg_pfnum >= firstfree && pte->pg_pfnum < maxfree && cmap[pgtocm(pte->pg_pfnum)].c_intrans) ! 362: count(p, pte, ZINTRAN); ! 363: else ! 364: count(p, pte, ZSTACK); ! 365: } ! 366: vprintf("\n"); ! 367: for (i = 0; i < UPAGES; i++) ! 368: count(p, &p->p_addr[i], ZUDOT); ! 369: vprintf("\n"); ! 370: vprintf("\n"); ! 371: } ! 372: for (xp = &text[0]; xp < text+ntext; xp++) ! 373: if (xp->x_iptr) { ! 374: int size = ctod(xp->x_size); ! 375: ! 376: for (i = 0; i < size; i += dmtext) ! 377: duse(xp->x_daddr[i], ! 378: (size - i) > dmtext ! 379: ? dmtext : size - i, ! 380: DTEXT, xp - text); ! 381: if (xp->x_flag & XPAGI) ! 382: duse(xp->x_ptdaddr, ! 383: ctod(clrnd(ctopt(xp->x_size))), ! 384: DTEXT, xp - text); ! 385: } ! 386: dmcheck(); ! 387: fixfree(); ! 388: summary(); ! 389: exit(0); ! 390: } ! 391: ! 392: pdmap() ! 393: { ! 394: register struct text *xp; ! 395: ! 396: if (fswap == -1 && (u.u_procp->p_flag & SLOAD) == 0) ! 397: return; ! 398: if (Dflg) ! 399: printf("disk for pid %d", u.u_procp->p_pid); ! 400: if ((xp = u.u_procp->p_textp) && Dflg) ! 401: ptdmap(xp->x_daddr, xp->x_size); ! 402: pdmseg("data", &u.u_dmap, DDATA); ! 403: pdmseg("stack", &u.u_smap, DSTACK); ! 404: if (Dflg) ! 405: printf("\n"); ! 406: } ! 407: ! 408: ptdmap(dp, size) ! 409: register daddr_t *dp; ! 410: int size; ! 411: { ! 412: register int i; ! 413: int rem; ! 414: ! 415: if (Dflg) ! 416: printf(" text:"); ! 417: for (i = 0, rem = size; rem > 0; i++) { ! 418: if (Dflg) ! 419: printf(" %x<%x>", dp[i], rem < dmtext ? rem : dmtext); ! 420: rem -= rem < dmtext ? rem : dmtext; ! 421: } ! 422: } ! 423: ! 424: pdmseg(cp, dmp, type) ! 425: char *cp; ! 426: struct dmap *dmp; ! 427: { ! 428: register int i; ! 429: int b, rem; ! 430: ! 431: if (Dflg) ! 432: printf(", %s:", cp); ! 433: b = dmmin; ! 434: for (i = 0, rem = dmp->dm_size; rem > 0; i++) { ! 435: if (Dflg) ! 436: printf(" %x<%x>", dmp->dm_map[i], rem < b ? rem : b); ! 437: duse(dmp->dm_map[i], b, type, u.u_procp - proc); ! 438: rem -= b; ! 439: if (b < dmmax) ! 440: b *= 2; ! 441: } ! 442: } ! 443: ! 444: duse(first, size, type, index) ! 445: { ! 446: register struct dblks *dp; ! 447: ! 448: if (fswap == -1) ! 449: return; ! 450: dp = &dblks[ndblks]; ! 451: if (++ndblks > 2*nswapmap) { ! 452: fprintf(stderr, "too many disk blocks\n"); ! 453: exit(1); ! 454: } ! 455: dp->d_first = first; ! 456: dp->d_size = size; ! 457: dp->d_type = type; ! 458: dp->d_index = index; ! 459: } ! 460: ! 461: dsort(d, e) ! 462: register struct dblks *d, *e; ! 463: { ! 464: ! 465: return (e->d_first - d->d_first); ! 466: } ! 467: ! 468: dmcheck() ! 469: { ! 470: register struct mapent *smp; ! 471: register struct dblks *d, *e; ! 472: ! 473: for (smp = swapmap; smp->m_size; smp++) ! 474: duse(smp->m_addr, smp->m_size, DFREE, 0); ! 475: duse(ctod(CLSIZE), dmtext - ctod(CLSIZE), DFREE, 0); ! 476: qsort(dblks, ndblks, sizeof (struct dblks), dsort); ! 477: d = &dblks[ndblks - 1]; ! 478: if (d->d_first > 1) ! 479: printf("lost swap map: start %x size %x\n", 1, d->d_first); ! 480: for (; d > dblks; d--) { ! 481: if (dflg) ! 482: dprint(d); ! 483: e = d - 1; ! 484: if (d->d_first + d->d_size > e->d_first) { ! 485: printf("overlap in swap mappings:\n"); ! 486: dprint(d); ! 487: dprint(e); ! 488: } else if (d->d_first + d->d_size < e->d_first) { ! 489: printf("lost swap map: start %x size %x\n", ! 490: d->d_first + d->d_size, ! 491: e->d_first - (d->d_first + d->d_size)); ! 492: } ! 493: } ! 494: if (dflg) ! 495: dprint(dblks); ! 496: if (sflg) ! 497: printf("swap space ends at %x\n", d->d_first + d->d_size); ! 498: } ! 499: ! 500: char *dnames[] = { ! 501: "DFREE", ! 502: "DDATA", ! 503: "DSTACK", ! 504: "DTEXT", ! 505: "DUDOT", ! 506: "DPAGET", ! 507: }; ! 508: ! 509: dprint(d) ! 510: register struct dblks *d; ! 511: { ! 512: ! 513: printf("at %4x size %4x type %s", d->d_first, d->d_size, ! 514: dnames[d->d_type]); ! 515: switch (d->d_type) { ! 516: ! 517: case DSTACK: ! 518: case DDATA: ! 519: printf(" pid %d", proc[d->d_index].p_pid); ! 520: break; ! 521: } ! 522: printf("\n"); ! 523: } ! 524: ! 525: getpt(x, i) ! 526: int x, i; ! 527: { ! 528: ! 529: lseek(fcore, (long)ctob((x & PG_PFNUM)), 0); ! 530: if (read(fcore, (char *)(p0br[i]), NBPG) != NBPG) { ! 531: perror("read"); ! 532: fprintf(stderr, "getpt error reading frame %x\n", clear(x)); ! 533: return (0); ! 534: } ! 535: return (1); ! 536: } ! 537: ! 538: checkpg(p, pte, type) ! 539: register struct pte *pte; ! 540: register struct proc *p; ! 541: int type; ! 542: { ! 543: char corepg[NBPG], swapg[NBPG]; ! 544: register int i, count, dblock; ! 545: register int pfnum = pte->pg_pfnum; ! 546: ! 547: if (type == ZPAGET || type == ZUDOT) ! 548: return (0); ! 549: lseek(fcore, (long)(NBPG * pfnum), 0); ! 550: if (read(fcore, corepg, NBPG) != NBPG){ ! 551: perror("read"); ! 552: fprintf(stderr, "Error reading core page %x\n", pfnum); ! 553: return (0); ! 554: } ! 555: switch (type) { ! 556: ! 557: case ZDATA: ! 558: if (ptetodp(p, pte) >= u.u_dmap.dm_size) ! 559: return (0); ! 560: break; ! 561: ! 562: case ZTEXT: ! 563: break; ! 564: ! 565: case ZSTACK: ! 566: if (ptetosp(p, pte) >= u.u_smap.dm_size) ! 567: return (0); ! 568: break; ! 569: ! 570: default: ! 571: return(0); ! 572: break; ! 573: } ! 574: dblock = vtod(p, ptetov(p, pte), &u.u_dmap, &u.u_smap); ! 575: vprintf(" %x", dblock); ! 576: if (pte->pg_fod || pte->pg_pfnum == 0) ! 577: return (0); ! 578: if (cmap[pgtocm(pte->pg_pfnum)].c_intrans || pte->pg_m || pte->pg_swapm) ! 579: return (0); ! 580: lseek(fswap, (long)(DEV_BSIZE * dblock), 0); ! 581: if (read(fswap, swapg, NBPG) != NBPG) { ! 582: fprintf(stderr,"swap page %x: ", dblock); ! 583: perror("read"); ! 584: } ! 585: count = 0; ! 586: for (i = 0; i < NBPG; i++) ! 587: if (corepg[i] != swapg[i]) ! 588: count++; ! 589: if (count == 0) ! 590: vprintf("\tsame"); ! 591: return (count); ! 592: } ! 593: ! 594: getu(p) ! 595: register struct proc *p; ! 596: { ! 597: int i, w, cc, errs = 0; ! 598: ! 599: if (uflg && (p->p_flag & SLOAD)) ! 600: printf("pid %d u. pages:", p->p_pid); ! 601: for (i = 0; i < UPAGES; i++) { ! 602: if (p->p_flag & SLOAD) { ! 603: if (uflg) ! 604: printf(" %x", p->p_addr[i].pg_pfnum); ! 605: lseek(fcore, ctob(p->p_addr[i].pg_pfnum), 0); ! 606: if (read(fcore, u_area.buf[i], NBPG) != NBPG) ! 607: perror("core u. read"), errs++; ! 608: } else if (fswap >= 0) { ! 609: lseek(fswap, (long)(NBPG * (p->p_swaddr+i)), 0); ! 610: if (read(fswap, u_area.buf[i], NBPG) != NBPG) ! 611: perror("swap u. read"), errs++; ! 612: } ! 613: } ! 614: if (uflg && (p->p_flag & SLOAD)) ! 615: printf("\n"); ! 616: return (errs); ! 617: } ! 618: ! 619: char *typepg[] = { ! 620: "lost", ! 621: "data", ! 622: "stack", ! 623: "udot", ! 624: "paget", ! 625: "text", ! 626: "free", ! 627: "intransit", ! 628: }; ! 629: ! 630: count(p, pte, type) ! 631: struct proc *p; ! 632: register struct pte *pte; ! 633: int type; ! 634: { ! 635: register int pfnum = pte->pg_pfnum; ! 636: register struct paginfo *zp = &paginfo[pfnum]; ! 637: int ndif; ! 638: #define zprintf if (type==ZINTRAN || vflg) printf ! 639: ! 640: if (type == ZINTRAN && pfnum == 0) ! 641: return; ! 642: zprintf("page %x %s", pfnum, typepg[type]); ! 643: if (sflg == 0 || (ndif = checkpg(p, pte, type)) == 0) { ! 644: zprintf("\n"); ! 645: } else { ! 646: if (vflg == 0 && type != ZINTRAN) ! 647: printf("page %x %s,", pfnum, typepg[type]); ! 648: printf(" %d bytes differ\n",ndif); ! 649: } ! 650: if (pfnum < firstfree || pfnum > maxfree) { ! 651: printf("page number out of range:\n"); ! 652: printf("\tpage %x type %s pid %d\n", pfnum, typepg[type], pid); ! 653: return; ! 654: } ! 655: if (bad(zp, type)) { ! 656: printf("dup page pte %x", *(int *)pte); ! 657: dumpcm("", pte->pg_pfnum); ! 658: dump(zp); ! 659: printf("pte %x and as %s in pid %d\n", zp->z_pte, typepg[type], pid); ! 660: return; ! 661: } ! 662: zp->z_type = type; ! 663: zp->z_count++; ! 664: zp->z_pid = pid; ! 665: zp->z_pte = *pte; ! 666: } ! 667: ! 668: bad(zp, type) ! 669: struct paginfo *zp; ! 670: { ! 671: if (type == ZTEXT) { ! 672: if (zp->z_type != 0 && zp->z_type != ZTEXT) ! 673: return (1); ! 674: return (0); ! 675: } ! 676: return (zp->z_count); ! 677: } ! 678: ! 679: dump(zp) ! 680: struct paginfo *zp; ! 681: { ! 682: ! 683: printf("page %x type %s pid %d ", zp - paginfo, typepg[zp->z_type], zp->z_pid); ! 684: } ! 685: ! 686: summary() ! 687: { ! 688: register int i; ! 689: register struct paginfo *zp; ! 690: register int pfnum; ! 691: ! 692: for (i = firstfree + UPAGES; i < maxfree; i+= CLSIZE) { ! 693: zp = &paginfo[i]; ! 694: if (zp->z_type == ZLOST) ! 695: dumpcm("lost", i); ! 696: pfnum = pgtocm(i); ! 697: if (cmap[pfnum].c_lock && cmap[pfnum].c_type != CSYS) ! 698: dumpcm("locked", i); ! 699: if (mflg) ! 700: dumpcm("mem", i); ! 701: } ! 702: } ! 703: ! 704: char *tynames[] = { ! 705: "sys", ! 706: "text", ! 707: "data", ! 708: "stack" ! 709: }; ! 710: dumpcm(cp, pg) ! 711: char *cp; ! 712: int pg; ! 713: { ! 714: int pslot; ! 715: int cm; ! 716: register struct cmap *c; ! 717: ! 718: cm = pgtocm(pg); ! 719: printf("cm %x %s page %x ", cm, cp, pg); ! 720: c = &cmap[cm]; ! 721: printf("\t[%x, %x", c->c_page, c->c_ndx); ! 722: if (c->c_type == CSYS) ! 723: goto skip; ! 724: if (c->c_type != CTEXT) { ! 725: if (c->c_ndx >= nproc) { ! 726: printf(" [text c->c_ndx %d?]", c->c_ndx); ! 727: goto skip; ! 728: } ! 729: printf(" (=pid %d)", proc[c->c_ndx].p_pid); ! 730: } else { ! 731: if (c->c_ndx >= ntext) { ! 732: printf(" [text c->c_ndx %d?]", c->c_ndx); ! 733: goto skip; ! 734: } ! 735: pslot= (text[c->c_ndx].x_caddr - aproc); ! 736: printf(" (=pid"); ! 737: for(;;) { ! 738: printf(" %d", proc[pslot].p_pid); ! 739: if (proc[pslot].p_xlink == 0) ! 740: break; ! 741: pslot= (proc[pslot].p_xlink - aproc); ! 742: } ! 743: printf(")"); ! 744: } ! 745: skip: ! 746: printf("] "); ! 747: printf(tynames[c->c_type]); ! 748: if (c->c_free) ! 749: printf(" free"); ! 750: if (c->c_gone) ! 751: printf(" gone"); ! 752: if (c->c_lock) ! 753: printf(" lock"); ! 754: if (c->c_want) ! 755: printf(" want"); ! 756: if (c->c_intrans) ! 757: printf(" intrans"); ! 758: if (c->c_blkno) ! 759: printf(" blkno %x mdev %d", c->c_blkno, c->c_mdev); ! 760: if (c->c_hlink) { ! 761: printf(" hlink %x page %x", c->c_hlink, cmtopg(c->c_hlink)); ! 762: if (c->c_hlink > ecmx) ! 763: printf(" <<<"); ! 764: } ! 765: printf("\n"); ! 766: } ! 767: ! 768: fixfree() ! 769: { ! 770: register int i, next, prev; ! 771: ! 772: next = CMHEAD; ! 773: for (i=freemem/CLSIZE; --i >=0; ) { ! 774: prev = next; ! 775: next = cmap[next].c_next; ! 776: if (cmap[next].c_free == 0) { ! 777: printf("link to non free block: in %x to %x\n", cmtopg(prev), cmtopg(next)); ! 778: dumpcm("bad free link in", cmtopg(prev)); ! 779: dumpcm("to non free block", cmtopg(next)); ! 780: } ! 781: if (cmtopg(next) > maxfree) { ! 782: printf("free list link out of range: in %x to %x\n", cmtopg(prev), cmtopg(next)); ! 783: dumpcm("bad link in", cmtopg(prev)); ! 784: } ! 785: paginfo[cmtopg(next)].z_type = ZFREE; ! 786: if (fflg) ! 787: dumpcm("free", cmtopg(next)); ! 788: paginfo[cmtopg(next)+1].z_type = ZFREE; ! 789: if (fflg) ! 790: dumpcm("free", cmtopg(next)+1); ! 791: } ! 792: } ! 793: ! 794: get(loc) ! 795: unsigned loc; ! 796: { ! 797: int x; ! 798: ! 799: lseek(fcore, (long)clear(loc), 0); ! 800: if (read(fcore, (char *)&x, sizeof (int)) != sizeof (int)) { ! 801: perror("read"); ! 802: fprintf(stderr, "get failed on %x\n", clear(loc)); ! 803: return (0); ! 804: } ! 805: return (x); ! 806: } ! 807: /* ! 808: * Convert a virtual page number ! 809: * to its corresponding disk block number. ! 810: * Used in pagein/pageout to initiate single page transfers. ! 811: */ ! 812: vtod(p, v, dmap, smap) ! 813: register struct proc *p; ! 814: register struct dmap *dmap, *smap; ! 815: { ! 816: struct dblock db; ! 817: ! 818: if (isatsv(p, v)) { ! 819: v = ctod(vtotp(p, v)); ! 820: return(p->p_textp->x_daddr[v / dmtext] + v % dmtext); ! 821: } ! 822: if (isassv(p, v)) ! 823: vstodb(ctod(vtosp(p, v)), ctod(1), smap, &db, 1); ! 824: else ! 825: vstodb(ctod(vtodp(p, v)), ctod(1), dmap, &db, 0); ! 826: return (db.db_base); ! 827: } ! 828: ! 829: /* ! 830: * Convert a pte pointer to ! 831: * a virtual page number. ! 832: */ ! 833: ptetov(p, pte) ! 834: register struct proc *p; ! 835: register struct pte *pte; ! 836: { ! 837: ! 838: if (isatpte(p, pte)) ! 839: return (tptov(p, ptetotp(p, pte))); ! 840: else if (isadpte(p, pte)) ! 841: return (dptov(p, ptetodp(p, pte))); ! 842: else ! 843: return (sptov(p, ptetosp(p, pte))); ! 844: } ! 845: ! 846: /* ! 847: * Given a base/size pair in virtual swap area, ! 848: * return a physical base/size pair which is the ! 849: * (largest) initial, physically contiguous block. ! 850: */ ! 851: vstodb(vsbase, vssize, dmp, dbp, rev) ! 852: register int vsbase; ! 853: int vssize; ! 854: register struct dmap *dmp; ! 855: register struct dblock *dbp; ! 856: { ! 857: register int blk = dmmin; ! 858: register swblk_t *ip = dmp->dm_map; ! 859: ! 860: if (vsbase < 0 || vsbase + vssize > dmp->dm_size) ! 861: panic("vstodb"); ! 862: while (vsbase >= blk) { ! 863: vsbase -= blk; ! 864: if (blk < dmmax) ! 865: blk *= 2; ! 866: ip++; ! 867: } ! 868: dbp->db_size = min(vssize, blk - vsbase); ! 869: dbp->db_base = *ip + (rev ? blk - (vsbase + vssize) : vsbase); ! 870: } ! 871: ! 872: panic(cp) ! 873: char *cp; ! 874: { ! 875: printf("panic!: %s\n", cp); ! 876: } ! 877: ! 878: min(a, b) ! 879: { ! 880: return (a < b ? a : b); ! 881: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.