PFMON.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:8k
源码类别:

Windows编程

开发平台:

Visual C++

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