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