home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / image / winnt / pfmon / pfmon.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  8KB  |  267 lines

  1. /*++
  2.  
  3. Copyright (c) 1995-1997  Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     pfmon.c
  8.  
  9. Abstract:
  10.  
  11.     USAGE: pfmon [pfmon switches] command-line-of-application
  12.  
  13.  
  14. Platform:
  15.  
  16.    PFMON will run only on Windows NT.
  17.     It requires psapi.dll which is distributed with the Win32 SDK.
  18.  
  19. Author:
  20.  
  21.     Mark Lucovsky (markl) 26-Jan-1995
  22.  
  23. --*/
  24.  
  25. #include "pfmonp.h"
  26.  
  27. #define WORKING_SET_BUFFER_ENTRYS 4096
  28. PSAPI_WS_WATCH_INFORMATION WorkingSetBuffer[WORKING_SET_BUFFER_ENTRYS];
  29.  
  30. #define MAX_SYMNAME_SIZE  1024
  31. CHAR PcSymBuffer[sizeof(IMAGEHLP_SYMBOL)+MAX_SYMNAME_SIZE];
  32. PIMAGEHLP_SYMBOL PcSymbol = (PIMAGEHLP_SYMBOL) PcSymBuffer;
  33. CHAR VaSymBuffer[sizeof(IMAGEHLP_SYMBOL)+MAX_SYMNAME_SIZE];
  34. PIMAGEHLP_SYMBOL VaSymbol = (PIMAGEHLP_SYMBOL) VaSymBuffer;
  35.  
  36.  
  37.  
  38. int
  39. main ()
  40. {
  41.     CHAR Line[256];
  42.  
  43.     if (!InitializePfmon()) {
  44.         ExitProcess( 1 );
  45.         }
  46.     else {
  47.         DebugEventLoop();
  48.         sprintf(Line,"\n PFMON: Total Faults %d  (KM %d UM %d Soft %d, Hard %d, Code %d, Data %d)\n",
  49.             TotalSoftFaults + TotalHardFaults,
  50.             TotalKernelFaults,
  51.             TotalUserFaults,
  52.             TotalSoftFaults,
  53.             TotalHardFaults,
  54.             TotalCodeFaults,
  55.             TotalDataFaults
  56.             );
  57.         fprintf(stdout,"%s",Line);
  58.         if ( LogFile ) {
  59.             fprintf(LogFile,"%s",Line);
  60.             fclose(LogFile);
  61.             }
  62.         ExitProcess( 0 );
  63.         }
  64.  
  65.     return 0;
  66. }
  67.  
  68. VOID
  69. ProcessPfMonData(
  70.     VOID
  71.     )
  72. {
  73.     BOOL b;
  74.     BOOL DidOne;
  75.     INT i;
  76.     PMODULE_INFO PcModule;
  77.     PMODULE_INFO VaModule;
  78.     DWORD PcOffset;
  79.     DWORD VaOffset;
  80.     CHAR PcLine[256];
  81.     CHAR VaLine[256];
  82.     CHAR PcModuleStr[256];
  83.     CHAR VaModuleStr[256];
  84.     LPVOID Pc;
  85.     LPVOID Va;
  86.     BOOL SoftFault;
  87.     BOOL CodeFault;
  88.     BOOL KillLog;
  89.     static int cPfCnt = 0;
  90.  
  91.  
  92.  
  93.     PcSymbol->SizeOfStruct  = sizeof(IMAGEHLP_SYMBOL);
  94.     PcSymbol->MaxNameLength = MAX_SYMNAME_SIZE;
  95.     VaSymbol->SizeOfStruct  = sizeof(IMAGEHLP_SYMBOL);
  96.     VaSymbol->MaxNameLength = MAX_SYMNAME_SIZE;
  97.  
  98.     //Get the buffer of recent page faults from the process's data structure
  99.     b = GetWsChanges(hProcess,&WorkingSetBuffer[0],sizeof(WorkingSetBuffer));
  100.  
  101.     if ( b ) {
  102.         DidOne = FALSE;
  103.         i = 0;
  104.         while (WorkingSetBuffer[i].FaultingPc) {
  105.             if ( WorkingSetBuffer[i].FaultingVa ) {
  106.                 Pc = WorkingSetBuffer[i].FaultingPc;
  107.                 Va = WorkingSetBuffer[i].FaultingVa;
  108.  
  109.  
  110.                 if ( (DWORD)Pc & 0x80000000 ) {
  111.                     TotalKernelFaults++;
  112.                     if ( !fKernel ) {
  113.                         i++;
  114.                         continue;
  115.                         }
  116.                     }
  117.                 else {
  118.                     TotalUserFaults++;
  119.                     if ( fKernelOnly ) {
  120.                         i++;
  121.                         continue;
  122.                         }
  123.                     }
  124.  
  125.                 //Check least sig bit which stores whether it was a hard
  126.                 //or soft fault
  127.  
  128.                 if ( (ULONG)Va & 1 ) {
  129.                     TotalSoftFaults++;
  130.                     SoftFault = TRUE;
  131.                     }
  132.                 else {
  133.                     TotalHardFaults++;
  134.                     SoftFault = FALSE;
  135.                     }
  136.  
  137.                 Va = (LPVOID)( (ULONG)Va & 0xfffffffe);
  138.                 if ( (LPVOID)((ULONG)Pc & 0xfffffffe) == Va ) {
  139.                     CodeFault = TRUE;
  140.                     TotalCodeFaults++;
  141.                     }
  142.                 else {
  143.                     TotalDataFaults++;
  144.                     CodeFault = FALSE;
  145.                     }
  146.  
  147.  
  148.                 PcModule = FindModuleContainingAddress(Pc);
  149.                 VaModule = FindModuleContainingAddress(Va);
  150.  
  151.                 if ( PcModule ) {
  152.                     PcModule->NumberCausedFaults++;
  153.                     sprintf(PcModuleStr, "%s", PcModule->DebugInfo->ImageFileName);
  154.                     }
  155.                 else {
  156.                     PcModuleStr[0] = '\0';
  157.                     }
  158.  
  159.                 //Va was either a code reference or global
  160.                 //reference as opposed to a heap reference
  161.  
  162.                 if ( VaModule ) {
  163.                     if ( SoftFault ) {
  164.                         VaModule->NumberFaultedSoftVas++;
  165.                         }
  166.                     else {
  167.                         VaModule->NumberFaultedHardVas++;
  168.                         }
  169.                     sprintf(VaModuleStr, "%s", VaModule->DebugInfo->ImageFileName);
  170.                     }
  171.                 else
  172.                     VaModuleStr[0] = '\0';
  173.  
  174.                 if (SymGetSymFromAddr(hProcess, (DWORD)Pc, &PcOffset, PcSymbol)) {
  175.                     if ( PcOffset ) {
  176.                         sprintf(PcLine,"%s+0x%x",PcSymbol->Name,PcOffset);
  177.                         }
  178.                     else {
  179.                         sprintf(PcLine,"%s",PcSymbol->Name);
  180.                         }
  181.                     }
  182.                 else {
  183.                     sprintf(PcLine,"0x%08x : ",Pc);
  184.                     }
  185.  
  186.                 if (SymGetSymFromAddr(hProcess, (DWORD)Va, &VaOffset, VaSymbol)) {
  187.                     if ( VaOffset ) {
  188.                         sprintf(VaLine,"%s+0x%x",VaSymbol->Name,VaOffset);
  189.                         }
  190.                     else {
  191.                         sprintf(VaLine,"%s",VaSymbol->Name);
  192.                         }
  193.                     }
  194.                 else {
  195.                     sprintf(VaLine,"0x%08x",Va);
  196.                     }
  197.  
  198.                 KillLog = FALSE;
  199.  
  200.                 if ( fCodeOnly && !CodeFault ) {
  201.                     KillLog = TRUE;
  202.                     }
  203.                 if ( fHardOnly && SoftFault ) {
  204.                     KillLog = TRUE;
  205.                     }
  206.  
  207.                 if ( !KillLog ) {
  208.                     if ( !fLogOnly ) {
  209.                         if (!fDatabase) {
  210.                             fprintf(stdout,"%s%s : %s\n",SoftFault ? "SOFT: " : "HARD: ",PcLine,VaLine);
  211.                             }
  212.                         else {
  213.  
  214.                             //Addresses are printed out in decimal
  215.                             //because most databases don't support
  216.                             //hex formats
  217.  
  218.                             fprintf(stdout,"%8d\t%s\t%s\t%s\t%u\t%s\t%s\t%u\n",
  219.                                     cPfCnt,
  220.                                     SoftFault ? "SOFT" : "HARD",
  221.                                     PcModuleStr,
  222.                                     PcLine,
  223.                                     (DWORD) Pc,
  224.                                     VaModuleStr,
  225.                                     VaLine,
  226.                                     (DWORD) Va);
  227.                             }
  228.                         }
  229.  
  230.                     if ( LogFile ) {
  231.                         if (!fDatabase) {
  232.                             fprintf(LogFile,"%s%s : %s\n",SoftFault ? "SOFT: " : "HARD: ",PcLine,VaLine);
  233.                             }
  234.                         else {
  235.                             fprintf(LogFile,"%8d\t%s\t%s\t%s\t%u\t%s\t%s\t%u\n",
  236.                                     cPfCnt,
  237.                                     SoftFault ? "SOFT" : "HARD",
  238.                                     PcModuleStr,
  239.                                     PcLine,
  240.                                     (DWORD) Pc,
  241.                                     VaModuleStr,
  242.                                     VaLine,
  243.                                     (DWORD) Va);
  244.                             }
  245.                         }
  246.                     DidOne = TRUE;
  247.                     cPfCnt++;
  248.                     }
  249.                 }
  250.             i++;
  251.             }
  252.  
  253.         if ( DidOne ) {
  254.             if ( !fLogOnly  && !fDatabase) {
  255.                 fprintf(stdout,"\n");
  256.                 }
  257.             }
  258.  
  259.         //If the buffer overflowed then a non-zero value for
  260.         //the Va was stored in the last record.
  261.         if ((ULONG)WorkingSetBuffer[i].FaultingVa)
  262.             fprintf(stdout,"Warning: Page fault buffer has overflowed\n");
  263.  
  264.  
  265.         }
  266. }
  267.