📄 msdump.c
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees * of Leland Stanford Junior University. * * This file is part of the SimOS distribution. * See LICENSE file for terms of the license. * *//***************************************************************** * msdump.c * * Utility to view the memstat.output* files. */ #include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <stdio.h>#include <string.h>#include <stddef.h>#include <stdlib.h>#ifdef __alpha#include <string.h>#else#include <bstring.h>#endif#include "memstatdump.h"#define MAXCPUS 32#define MAX_SYMBOLS 1000000typedef char Bucket[1024]; /* sizeof(MemStatIbucket)] */VA symAddr=0;VA nextAddr=0;VA firstAddr = 0;VA lastAddr = 0;int currentSymbol = 0;Bucket gBucket[MAXCPUS];Bucket sumBucket;Resolution prevRes = Low;int CPUs = 0;int intsPerBucket =0;long outputList[32];int numOutput;char *memFileName = "memstat.output";char *symFileName = "unix.sym";int nSymbols;VA symbolAddr[MAX_SYMBOLS];char *symbolText[MAX_SYMBOLS];char symbolStrings[MAX_SYMBOLS*32];int rawOutput = 0;void AddToSymbol(VA addr,Bucket *bucket,int cpus);void DisplayRange(VA addr,VA firstaddr,VA lastAddr);int ComputeValues(Bucket *bucket,int cpus);void DisplayValue(Bucket *bucket,int off,int cpus, Bucket *b,char *format);void DisplayFormat(int cpus,VA addr,VA firstAddr,VA lastAddr);void DisplayRes( Resolution res );void DumpSymbol(Resolution res,VA sAddr,int cpus);void RawBucketsIters(VA addr, Bucket *bucket,Resolution res);void ProcessBuckets(VA addr, void *bucket,Resolution res) ;void process_args(int arggc,char **argv);void process_dumpfile(char *name) ;void ReadSymbolFile(char *filename) { FILE *sfd; VA addr; char dummy[128], name[128], buf[128],*stringPtr = symbolStrings; int i; sfd = fopen(filename,"r"); if( sfd == NULL ) { fprintf(stderr,"symbol file '%s' not found \n",filename); exit(1); } for(i=0;i<MAX_SYMBOLS;i++) { if ( GetLineFromFile(sfd,buf,128) && sscanf(buf,"%lx %s %s",&addr,dummy,name) ==3 ) { strcpy(stringPtr,name); symbolAddr[nSymbols] = addr; symbolText[nSymbols] = stringPtr; nSymbols++; while(*stringPtr) { stringPtr++; } stringPtr++; } else { break; } } if( i == MAX_SYMBOLS ) { fprintf(stderr,"too many symbols in %s, recompile msdump\n",filename); exit(1); } symbolAddr[nSymbols] = (VA)-1L; strcpy(stringPtr,"EOF");} void AddToSymbol(VA addr, Bucket *bucket,int cpus){ int i,j; for(i=0;i<cpus;++i) { if( msHeader.entrySize == 4 ) { uint *sum = (uint *)gBucket; uint *add = (uint *)bucket; for(j=0;j<intsPerBucket;++j) { *sum++ += *add++; } } if( msHeader.entrySize == 8 ) { uint64 *sum = (uint64 *)gBucket; uint64 *add = (uint64 *)bucket; for(j=0;j<intsPerBucket;++j) { *sum++ += *add++; } } } if( !firstAddr ) { firstAddr = addr; lastAddr = addr; } else { if( firstAddr > addr ) firstAddr = addr; if( lastAddr < addr ) lastAddr = addr; }} void DisplayRange(VA addr,VA firstAddr,VA lastAddr){ printf("\t%08lx:%08lx",firstAddr,lastAddr);}int ComputeValues(Bucket *bucket, int cpus){ int i,j; if( cpus == 1 ) { bcopy(bucket,(void*)sumBucket,sizeof(sumBucket)); } else { fprintf(stderr," not implemented \n"); bzero(sumBucket,sizeof(sumBucket)); for(i=0;i<cpus;i++) { for(j=0;j<intsPerBucket;j++) { sumBucket[j] += bucket[i][j]; } } } if( msHeader.entrySize == 4) { uint *ptr = (uint *) &sumBucket[0]; for(j=0;j<numOutput;j++) { if( ptr[outputList[j]] ) return 1; } } if( msHeader.entrySize == 8) { uint64 *ptr = (uint64 *) &sumBucket[0]; for(j=0;j<numOutput;j++) { if( ptr[outputList[j]] ) return 1; } } return 0;}void DisplayRes( Resolution res ){ switch( res ) { case Low: printf("MSD-L-"); break; case High: printf("MSD-H-"); break; case Detail: printf("MSD-W-"); break; }} #ifdef __alpha#define LLDSTRING "\t%8ld"#else#define LLDSTRING "\t%8lld"#endifvoid DumpSymbol(Resolution res,VA sAddr,int cpus){ int i; static int first = 0; int last; i = ComputeValues(gBucket,cpus); if( res == Low ) lastAddr += msHeader.lowRes-1; if( res == High ) lastAddr += msHeader.highRes-1; if( i ) { DisplayRes(res); for(i=0;i<numOutput;i++) { if( msHeader.entrySize == 4 ) { uint *ptr = (uint *) &sumBucket[0]; printf(LLDSTRING ,(uint64)ptr[outputList[i]]); } if( msHeader.entrySize == 8 ) { uint64 *ptr = (uint64 *) &sumBucket[0]; printf(LLDSTRING,ptr[outputList[i]]); } } DisplayRange(sAddr,firstAddr,lastAddr); if( symbolAddr[first] > firstAddr ) first = 0; while( symbolAddr[first+1] <= firstAddr ) { first++; } for(last=first; symbolAddr[last] <= lastAddr && lastAddr != 0xffffffff; last++) { } if( last - first > 4 ) { printf("\t%s,%s...%s,%s\n",symbolText[first],symbolText[first+1], symbolText[last-2],symbolText[last-1]); } else { printf("\t"); for(i=first;i<last-1;i++) { printf("%s,",symbolText[i]); } printf("%s\n",symbolText[last-1]); } } firstAddr = 0; bzero(gBucket,sizeof(gBucket));}VA GetSymbol(void){ if (currentSymbol>=nSymbols) { return 0xffffffff; } else { return symbolAddr[currentSymbol++]; }} void ProcessBuckets(VA addr, void *ptr, Resolution res) { uint resModmask; VA additionalAddr; int i; Bucket *bucket = ptr; int dump = 0; int size; i = ComputeValues(bucket,CPUs); if( !i ) return; fprintf(stderr, "ProcessBuckets(va=%lx res=%d) ComputeValues returned %d\n", addr, res, i); if( res==Low ) size = msHeader.lowRes; if( res==High) size = msHeader.highRes; if( res==Detail ) size = 4; if( rawOutput ) dump = 1; if( prevRes!= res ) dump = 1; if( addr +size >= nextAddr ) dump = 1; if( !dump ) { AddToSymbol(addr,bucket,CPUs); prevRes = res; return; } if( prevRes== Low && res != Low ) { currentSymbol = 0; symAddr = GetSymbol(); nextAddr = GetSymbol(); } if( symAddr == 0 ) { while( nextAddr <= addr + size ) { symAddr = nextAddr; nextAddr = GetSymbol(); } } if( res == prevRes && prevRes!=Detail && res!=Detail ) { if( res==Low ) resModmask = ~(msHeader.lowRes-1); else resModmask = ~(msHeader.highRes-1); additionalAddr = nextAddr; while( lastAddr == (additionalAddr & resModmask) ) { additionalAddr = GetSymbol(); } } DumpSymbol(prevRes,symAddr,CPUs); AddToSymbol(addr,bucket,CPUs); while ( addr + size > nextAddr ) { symAddr = nextAddr; nextAddr = GetSymbol(); } prevRes = res;} void process_args(int argc, char **argv) { int i=0; extern char* optarg; extern int optind; int c; while ((c = getopt(argc, argv, "idrs:m:")) != EOF) { switch( c ) { case 's': symFileName = optarg; break; case 'm': memFileName = optarg; break; case 'r': rawOutput = 1; break; case '?': fprintf(stderr,"Use: msdump [-s symbol_file] [-m memstat.output] {counter} \n"); exit(1); } } for(; optind < argc; optind++) { /* for now, only offsets */ outputList[numOutput++] = atoi(argv[optind]); } fprintf(stderr,"executing msdump -s %s -m -%s",symFileName, memFileName); for(i=0;i<numOutput;i++) fprintf(stderr," %d",outputList[i]); fprintf(stderr,"\n");} void process_dumpfile(char *name) { char dummy[64]; char tableType[16]; int i; symAddr=0; nextAddr =0; currentSymbol = 0; symAddr = GetSymbol(); nextAddr = GetSymbol(); if( MemStatFileOpen(name) ==-1) return; if( sscanf(msHeader.tableName,"%s %s %i",dummy,tableType,&i) == 3 ) { if( i ) CPUs = i; else CPUs = 1; if( !strcmp(tableType,"Std") ) { intsPerBucket = msHeader.bucketSize / msHeader.entrySize; fprintf(stderr," Generated by std SimOS, CPUs=%i\n",CPUs); } else{ intsPerBucket = 0/4; fprintf(stderr," Generated by TangoSimos CPUs=%i\n",CPUs); } } else { fprintf(stderr,"msdump version %d \n",msHeader.version); CPUs = 1; intsPerBucket = msHeader.bucketSize /msHeader.entrySize; } /* * eliminate outputs out of range */ i = 0; while (i<numOutput) { if (outputList[i] < 0 || outputList[i]>intsPerBucket) { fprintf(stderr,"Output column %d out of range! \n",outputList[i]); outputList[i] = outputList[numOutput-1]; numOutput--; } else { i++; } } if (!numOutput) { for(i=0;i<intsPerBucket;i++) { outputList[i] = i; } numOutput = intsPerBucket; } MemStatFileIterate(ProcessBuckets); DumpSymbol(prevRes,symAddr,CPUs);}main(int argc, char **argv){ fprintf(stderr, "sizeof(VA)=%d\n", sizeof(VA)); process_args(argc, argv); ReadSymbolFile(symFileName); prevRes = Low; process_dumpfile(memFileName); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -