home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / c / prf.arc / PRFPRINT.C < prev    next >
Text File  |  1988-11-24  |  4KB  |  184 lines

  1. /*
  2.  * This routine merges a profile.out file and a 
  3.  * microsoft linker map file to produce an approximate listing
  4.  * of times spent in each routine.
  5.  */
  6. #define NAMESIZE 12
  7. #define TAB_SIZE 512
  8. #include <stdio.h>
  9. #include <ctype.h>
  10.  
  11. main(int argc,char *argv[])
  12. {
  13.     extern int usage(),process();
  14.  
  15.     if( argc != 2){
  16.         return usage();
  17.     }
  18.     else {
  19.         return process( argv[1] );
  20.     }
  21.         
  22. }
  23. usage()
  24. {
  25.     fprintf(stderr,"USAGE: makeat <mapfile>\n");
  26.     return 1;
  27. }
  28. static contains(char *s,char *substr)
  29. {
  30.     int substrlen,len;
  31.     register char *p;
  32.     substrlen = strlen(substr);
  33.  
  34.     for( p = s ; *p ; p++){
  35.         if( *p != *substr)continue;
  36.         if(strncmp(substr,p,substrlen) == 0)return 1;
  37.     }
  38.     return 0;
  39. }
  40.  
  41. process(char *mapfile)
  42. {
  43.     FILE *fp,*fx;
  44.     unsigned int total;
  45.     char line[256];
  46.  
  47.     if((fp = fopen(mapfile,"r")) == NULL){
  48.         perror(mapfile);
  49.         return 1;
  50.     }
  51.     
  52.  
  53.     
  54.     /*
  55.        * this routine depends critically on the EXACT
  56.      * format of the Microsoft linker map file.
  57.      * we expect the line ' Publics by Value ' to 
  58.      * appear, followed by lines of the form ' 'cs:ip name
  59.      * (note the preceding blank)
  60.      * These lines appear continuously until the end of the section.
  61.      * so as soon as we encounter a line with the second character a 
  62.      * non-digit we stop.
  63.      */
  64.     
  65.     /* SEARCH FOR RELEVANT SECTION */
  66.     while (  ! feof(fp) ){
  67.         if( NULL == fgets ( line, sizeof(line) , fp )){
  68.             perror(mapfile);
  69.             fclose(fp); 
  70.             return 1;
  71.         }
  72.         /* only get out if we test equal... */
  73.         if(contains(line,"Publics by Value"))break;
  74.     }
  75.     while ( fgets(line,sizeof(line),fp) && ! isxdigit(line[1]) );
  76.         
  77.     for(;(!feof(fp)) && isxdigit(line[1]) ; fgets(line,sizeof(line),fp))
  78.     {
  79.         short cs,ip;
  80.         char name[32],junk[32];
  81.         if( sscanf(line,"%x:%x %s %s",&cs,&ip,name,junk) !=3 )continue;
  82.         insert(name,ip);
  83.     }
  84.  
  85.     /*
  86.      * we now have a sorted table of names versus ip 
  87.      * ( there are some subtleties in insert..... )
  88.      * 
  89.      * so now we open profil.out and merge info from there into
  90.      * the table and print the output.....
  91.      */
  92.     if((fx = fopen("PROFIL.OUT","r") ) == NULL){
  93.         perror("PROFIL.OUT");
  94.         return 1;
  95.     }
  96.     total = 0;
  97.     while( ! feof(fx) && fgets(line,sizeof(line), fx) != NULL){
  98.  
  99.         short ip,cnt;
  100.         if( sscanf(line,"%x %d",&ip,&cnt) != 2)continue;
  101.         total += cnt;
  102.         merge(ip, cnt);
  103.     }
  104.     fclose(fx);
  105.     fclose(fp);
  106.     dump(total);
  107.  
  108. }
  109. typedef struct {
  110.     char name[NAMESIZE];
  111.     unsigned short ip;
  112.     unsigned short cnt;
  113. } element;
  114. static element table[TAB_SIZE];
  115. static int table_ptr = 0;
  116. static int no_more_add = 0;
  117. insert(char *name, unsigned short ip)
  118. {
  119.     if( no_more_add    )return 1;
  120.     if ( table_ptr >= TAB_SIZE ){
  121.         fprintf(stderr,"Table Full \n");
  122.     }
  123.  
  124.         
  125.     /*
  126.      * if we move into a new segment then IP will drop and so
  127.      * we just stop adding.......
  128.      */
  129.         
  130.     if( table_ptr > 0 && ip < table[table_ptr-1].ip)
  131.         return (no_more_add = 1);
  132.  
  133.     name[sizeof(table[0].name)-1] = 0;
  134.     strcpy(table[table_ptr].name, name);
  135.     
  136.     table[table_ptr].ip = ip;
  137.     table[table_ptr].cnt = 0;
  138.     table_ptr++;
  139.     strcpy(table[table_ptr].name,"???");
  140.     table[table_ptr].ip = 0xFFFF;
  141.     
  142.     return 0;
  143. }
  144. merge(unsigned short ip,unsigned short cnt)
  145. {
  146.     register element *p;
  147.  
  148.     for( p = table ; p < table + table_ptr  ; p++){
  149.         if( ip < (p+1)->ip ){
  150.             p->cnt += cnt;
  151.             break;
  152.         }
  153.     }
  154.     return;
  155. }
  156. dump(unsigned int total)
  157. {
  158.     FILE *out;
  159.     register int i;
  160.     register element *p;
  161.     float percent;
  162.     unsigned int table_total = 0;
  163.  
  164.  
  165.  
  166.     for( i = 0 ; i < table_ptr ; i++){
  167.         p = &(table[i]);
  168.         if( p->cnt != 0)
  169.             percent = (p->cnt*100.0)/((float)total);
  170.         else 
  171.             percent = 0.0;
  172.         printf("%-16s %d %5.2f%%\n",p->name,p->cnt,percent);
  173.         table_total += p->cnt;
  174.     }
  175.     printf("------------------"); fflush(stdout);
  176.     percent = (100.0 * table_total)/((float)total);
  177.     printf("Above entries account for %5.2f%% of total time\n",percent);
  178.     printf("                 ( %d out of %d samples)\n",table_total,total);
  179.     fflush(stdout);
  180.     fclose(out);    
  181.     return;
  182. }
  183.  
  184.