/* * * This is a program to analyse the contents * of the proc array, found in a dump of memory * after a crash. * * P. Ivanov. UNSW. 14-4-77. * * P. Ivanov. UNSW. April-78 * */ #include "proc.h" char *corefile "/srce/usr/sys/sysdump/cores/core"; char *namelist "/srce/usr/sys/sysdump/unices/unix"; #ifdef ZOMBIE #define ZOMBIE (pp->p_stat == SZOMB) #endif main(argc, argv) int argc; char *argv[]; { extern bomb(); extern fout; register int p, q; register struct proc *pp; int r; struct symbol *procs, *currs; long l1, l2; int start, stop; int sz; fout = dup(1); pflg--; /*for (p = 1; p <= NSIG; p++) signal(p, bomb);*/ if (--argc > 0 && *argv[1] == '-') { argv++; while (*(++*argv) != '\0') switch (**argv) { case 'a': aflg++; capfflg++; continue; case 'b': bflg++; capfflg++; continue; case 'c': cflg++; capfflg++; continue; case 'C': capcflg++; continue; case 'd': dflg++; continue; case 'f': fflg++; continue; case 'F': aflg++; bflg++; cflg++; capfflg++; oflg++; continue; case 'g': gflg++; continue; case 'i': iflg++; continue; case 'k': kflg++; continue; case 'l': lflg++; continue; case 'n': nflg++; continue; case 'o': oflg++; capfflg++; continue; case 'p': /* default process when 'p' alone is 0 */ pflg = 0; for ((*argv)++; (**argv >= '0') && (**argv <= '9'); (*argv)++) pflg = (pflg * 10) + **argv - '0'; (*argv)--; if (pflg<0 || pflg>NPROC) crash("process request out of range"); continue; case 's': sflg++; continue; case 'S': capsflg++; continue; case 't': tflg++; continue; case 'u': uflg++; continue; case 'w': wflg++; continue; case 'x': xflg++; continue; case 'y': yflg++; continue; case 'z': zflg++; aflg++; bflg++; cflg++; fflg++; capfflg++; gflg++; iflg++; lflg++; oflg++; sflg++; tflg++; uflg++; xflg++; yflg++; continue; default: continue; } argc--; } DEBUG quest("args decoded, continue ??"); if (--argc >= 0) corefile = *(++argv); printf("core image file used was \"%s\"\n", corefile); /* get the name list for future reference */ if (nflg) if (--argc >= 0) namelist = *(++argv); else crash("Can't find namelist arg"); printf("namelist file used was \"%s\"\n\n", namelist); if ((namefd = open(namelist, 0)) < 0) crash("No namelist file!"); /* alloc and setup */ symsort(); procs = albin("_proc\0\0\0"); /* open the core file */ if ((corefd = open(corefile, 0)) < 0) crash("No core file"); /* * this section proper dumps the proc array, * if it can find it that is...... */ DEBUG printf("read registers and "); if (read(corefd, ®s, sizeof regs) < 0) crash("Can't read registers"); DEBUG printf("seek to \"_proc\" at %o ", procs->s_symval); seek(corefd, procs->s_symval, 0); DEBUG printf("successfully\n"); if (read(corefd, proc, sizeof proc) < 0) crash("Can't read proc array"); /* now decode the contents */ /* the registers are always useful */ putregs(); /* the maps if required */ getmap(); /* one or many */ if (pflg < 0) { start = 0; stop = NPROC; } else start = stop = pflg; /* first decode the p_stat codes */ for (p = start; p <= stop; p++) { pp = &proc[p]; if (!lflg && (pp->p_stat == 0)) continue; page(); printf("\n\nProcess_______ Slot____ %d (%o) at__ address_______ %d (%o)\n\n", p, p, procs->s_symval + p * sizeof proc[0], procs->s_symval + p * sizeof proc[0]); if (capfflg) { l1 = procs->s_symval.unsign; l2 = sizeof proc[0]; odump(l1 + (p * sizeof proc[0]), l2); } printf("\"p_stat\" indicates this process was "); if (pp->p_stat>=0 && pp->p_stat<=NOSTAT) { printf("%s", stat[pp->p_stat]); if (pp->p_addr == regs.r_kisa6) warn("this process was running_______"); } else { printf("in an impossible state (%o)\n", pp->p_stat); WARNING warn(""); } /* now flag codes */ printf("and \"p_flag\" says it was "); if (pp->p_flag == 0) printf("swapped out"); else for (q = 0; q < NOFLAG ; q++) if ((pp->p_flag >> q) & 01) printf("%s", flag[q]); printf(".\n\n"); /* now signals */ printf("Last signal \"p_sig\" received was %d (%o) - ", pp->p_sig, pp->p_sig); if (pp->p_sig>=0 && pp->p_sig<=NSIG) printf("%s\n\n", signals[pp->p_sig]); else { printf("impossible\n\n"); WARNING warn(""); } /* other variables */ #ifdef ZOMBIE /* either a zombie or not.... ie pz_shit or p_shit */ if(ZOMBIE) { /* pz_shit */ printf("%5t\"p_pri\""); #ifdef AUSAM16 printf("%29t\"p_uid\""); #endif printf("%65tscheduling%108tprocess\n"); printf("(negative is high)"); printf("%22tvalue%38towner"); #ifdef AUSAM16 printf("%48t\"p_time\""); #endif printf("%65t\"p_cpu\"%100t\"p_pid\"%117t\"p_ppid\"\n\n"); printf("%2t%d (%o)", pp->p_pri, pp->p_pri); #ifdef AUSAM16 printf("%22t%d (%o)%38t%s", pp->p_uid, pp->p_uid, getuser(pp->p_uid)); printf("%48t%d (%o)", pp->p_time, pp->p_time); #endif printf("%65t%d (%o)", pp->p_cpu, pp->p_cpu); printf("%100t%d (%o)", pp->p_pid, pp->p_pid); printf("%117t%d (%o)\n\n", pp->p_ppid, pp->p_ppid); printf("%22t\"pz_ur0\" = %u (%o) /// (%o, %o)\n\n", pp->pz_ur0, pp->pz_ur0, pp->pz_ur0.lobyte, pp->pz_ur0.hibyte); printf("%22t\"pz_utime\" = %D (%O) tix; %D sec.\n", pp->pz_utime, pp->pz_utime, pp->pz_utime/HZ); printf("%22t\"pz_stime\" = %D (%O) tix; %D sec.\n", pp->pz_stime, pp->pz_stime, pp->pz_stime/HZ); printf("\n\n"); } else { #endif ZOMBIE printf("%5t\"p_pri\""); printf("%29t\"p_uid\""); printf("%65tscheduling%108tprocess\n"); printf("(negative is high)"); printf("%22tvalue%38towner"); printf("%48t\"p_time\""); printf("%65t\"p_cpu\"%82t\"p_nice\"%100t\"p_pid\"%117t\"p_ppid\"\n\n"); printf("%2t%d (%o)", pp->p_pri, pp->p_pri); printf("%22t%d (%o)%38t%s", pp->p_uid, pp->p_uid, getuser(pp->p_uid)); printf("%48t%d (%o)", pp->p_time, pp->p_time); printf("%65t%d (%o)", pp->p_cpu, pp->p_cpu); printf("%82t%d (%o)", pp->p_nice, pp->p_nice); printf("%100t%d (%o)", pp->p_pid, pp->p_pid); printf("%117t%d (%o)\n\n", pp->p_ppid, pp->p_ppid); #ifdef ZOMBIE } #endif ZOMBIE /* now for other values */ printf("Controlling tty structure \"p_ttyp\" at address %d (%o) \n\n", pp->p_ttyp, pp->p_ttyp); /* decode the tty structure */ if (yflg && (pp->p_ttyp != NULL)) ttydecode(pp->p_ttyp); #ifdef ZOMBIE if (!ZOMBIE) { #endif printf("Swappable image \"p_addr\" at %d (%o) ", pp->p_addr, pp->p_addr); printf("of size \"p_size\" %d (%o) * 64 bytes\n\n", pp->p_size, pp->p_size); /* decode the u area */ if (pp->p_flag & (SLOAD | SLOCK)) { if(infree(coremap, pp->p_size, pp->p_addr)) warn("user area is in free core"); udecode(pp->p_addr, pp->p_size, procs->s_symval + (p * sizeof proc[0])); } /* is process on disc ok ? */ if(pp->p_flag & (SSWAP | SLOCK)) if(infree(swapmap, (pp->p_size + 7) >> 3, pp->p_addr)) warn("disc image in free swap space"); /* what is process waiting for */ printf("Process is "); if (pp->p_wchan == 0) printf("not waiting\n\n"); else { currs = getnum(pp->p_wchan, 0); printf("waiting on %d (%o)", pp->p_wchan, pp->p_wchan); printf(" at %8.8s", currs->s_symbol); r = pp->p_wchan - currs->s_symval; for(q=0, sz=0; symbols[q].st_sym[0] != 0; q++) { if(alcom(symbols[q].st_sym,currs->s_symbol) == 0) sz=symbols[q].st_sz; } if (sz != 0) { printf("[%d.]", r/sz); r =% sz; } if (r != 0) printf(" + %d (%o)", r, r); printf("\n\n"); } printf("Text structure \"*p_textp\" was at %d (%o)\n\n", pp->p_textp, pp->p_textp); if (xflg && pp->p_textp) textdecode(pp->p_textp); #ifdef ZOMBIE } #endif if (tflg) { printf("Forking tree from this process is as follows:"); treedecode(p); } dash(); } flush(); } quest(string) char *string; { printf("%s\nreturn to continue, else rubout\n", string); flush(); read(0, wkbuf, 2); } crash(string) char *string; { printf("proc: %s\n", string); flush(); exit(0); } warn(msg) char *msg; { printf("%119s%120t%s\n", msg, " *** NOTE ***"); } page() { putchar('\f'); } dash() { register p; for (p = 0; p < LINEWIDTH; p++) putchar('-'); putchar('\n'); } star() { register p; for (p = 0; p < LINEWIDTH; p++) putchar('*'); putchar('\n'); }