Annotation of cci/usr/src/etc/analyze.c, revision 1.1

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

unix.superglobalmegacorp.com

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