PFMON.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:8k
源码类别:
Windows编程
开发平台:
Visual C++
- /*++
- Copyright (c) 1995-1997 Microsoft Corporation
- Module Name:
- pfmon.c
- Abstract:
- USAGE: pfmon [pfmon switches] command-line-of-application
- Platform:
- PFMON will run only on Windows NT.
- It requires psapi.dll which is distributed with the Win32 SDK.
- Author:
- Mark Lucovsky (markl) 26-Jan-1995
- --*/
- #include "pfmonp.h"
- #define WORKING_SET_BUFFER_ENTRYS 4096
- PSAPI_WS_WATCH_INFORMATION WorkingSetBuffer[WORKING_SET_BUFFER_ENTRYS];
- #define MAX_SYMNAME_SIZE 1024
- CHAR PcSymBuffer[sizeof(IMAGEHLP_SYMBOL)+MAX_SYMNAME_SIZE];
- PIMAGEHLP_SYMBOL PcSymbol = (PIMAGEHLP_SYMBOL) PcSymBuffer;
- CHAR VaSymBuffer[sizeof(IMAGEHLP_SYMBOL)+MAX_SYMNAME_SIZE];
- PIMAGEHLP_SYMBOL VaSymbol = (PIMAGEHLP_SYMBOL) VaSymBuffer;
- int
- main ()
- {
- CHAR Line[256];
- if (!InitializePfmon()) {
- ExitProcess( 1 );
- }
- else {
- DebugEventLoop();
- sprintf(Line,"n PFMON: Total Faults %d (KM %d UM %d Soft %d, Hard %d, Code %d, Data %d)n",
- TotalSoftFaults + TotalHardFaults,
- TotalKernelFaults,
- TotalUserFaults,
- TotalSoftFaults,
- TotalHardFaults,
- TotalCodeFaults,
- TotalDataFaults
- );
- fprintf(stdout,"%s",Line);
- if ( LogFile ) {
- fprintf(LogFile,"%s",Line);
- fclose(LogFile);
- }
- ExitProcess( 0 );
- }
- return 0;
- }
- VOID
- ProcessPfMonData(
- VOID
- )
- {
- BOOL b;
- BOOL DidOne;
- INT i;
- PMODULE_INFO PcModule;
- PMODULE_INFO VaModule;
- DWORD PcOffset;
- DWORD VaOffset;
- CHAR PcLine[256];
- CHAR VaLine[256];
- CHAR PcModuleStr[256];
- CHAR VaModuleStr[256];
- LPVOID Pc;
- LPVOID Va;
- BOOL SoftFault;
- BOOL CodeFault;
- BOOL KillLog;
- static int cPfCnt = 0;
- PcSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
- PcSymbol->MaxNameLength = MAX_SYMNAME_SIZE;
- VaSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
- VaSymbol->MaxNameLength = MAX_SYMNAME_SIZE;
- //Get the buffer of recent page faults from the process's data structure
- b = GetWsChanges(hProcess,&WorkingSetBuffer[0],sizeof(WorkingSetBuffer));
- if ( b ) {
- DidOne = FALSE;
- i = 0;
- while (WorkingSetBuffer[i].FaultingPc) {
- if ( WorkingSetBuffer[i].FaultingVa ) {
- Pc = WorkingSetBuffer[i].FaultingPc;
- Va = WorkingSetBuffer[i].FaultingVa;
- if ( (DWORD)Pc & 0x80000000 ) {
- TotalKernelFaults++;
- if ( !fKernel ) {
- i++;
- continue;
- }
- }
- else {
- TotalUserFaults++;
- if ( fKernelOnly ) {
- i++;
- continue;
- }
- }
- //Check least sig bit which stores whether it was a hard
- //or soft fault
- if ( (ULONG)Va & 1 ) {
- TotalSoftFaults++;
- SoftFault = TRUE;
- }
- else {
- TotalHardFaults++;
- SoftFault = FALSE;
- }
- Va = (LPVOID)( (ULONG)Va & 0xfffffffe);
- if ( (LPVOID)((ULONG)Pc & 0xfffffffe) == Va ) {
- CodeFault = TRUE;
- TotalCodeFaults++;
- }
- else {
- TotalDataFaults++;
- CodeFault = FALSE;
- }
- PcModule = FindModuleContainingAddress(Pc);
- VaModule = FindModuleContainingAddress(Va);
- if ( PcModule ) {
- PcModule->NumberCausedFaults++;
- sprintf(PcModuleStr, "%s", PcModule->DebugInfo->ImageFileName);
- }
- else {
- PcModuleStr[0] = ' ';
- }
- //Va was either a code reference or global
- //reference as opposed to a heap reference
- if ( VaModule ) {
- if ( SoftFault ) {
- VaModule->NumberFaultedSoftVas++;
- }
- else {
- VaModule->NumberFaultedHardVas++;
- }
- sprintf(VaModuleStr, "%s", VaModule->DebugInfo->ImageFileName);
- }
- else
- VaModuleStr[0] = ' ';
- if (SymGetSymFromAddr(hProcess, (DWORD)Pc, &PcOffset, PcSymbol)) {
- if ( PcOffset ) {
- sprintf(PcLine,"%s+0x%x",PcSymbol->Name,PcOffset);
- }
- else {
- sprintf(PcLine,"%s",PcSymbol->Name);
- }
- }
- else {
- sprintf(PcLine,"0x%08x : ",Pc);
- }
- if (SymGetSymFromAddr(hProcess, (DWORD)Va, &VaOffset, VaSymbol)) {
- if ( VaOffset ) {
- sprintf(VaLine,"%s+0x%x",VaSymbol->Name,VaOffset);
- }
- else {
- sprintf(VaLine,"%s",VaSymbol->Name);
- }
- }
- else {
- sprintf(VaLine,"0x%08x",Va);
- }
- KillLog = FALSE;
- if ( fCodeOnly && !CodeFault ) {
- KillLog = TRUE;
- }
- if ( fHardOnly && SoftFault ) {
- KillLog = TRUE;
- }
- if ( !KillLog ) {
- if ( !fLogOnly ) {
- if (!fDatabase) {
- fprintf(stdout,"%s%s : %sn",SoftFault ? "SOFT: " : "HARD: ",PcLine,VaLine);
- }
- else {
- //Addresses are printed out in decimal
- //because most databases don't support
- //hex formats
- fprintf(stdout,"%8dt%st%st%st%ut%st%st%un",
- cPfCnt,
- SoftFault ? "SOFT" : "HARD",
- PcModuleStr,
- PcLine,
- (DWORD) Pc,
- VaModuleStr,
- VaLine,
- (DWORD) Va);
- }
- }
- if ( LogFile ) {
- if (!fDatabase) {
- fprintf(LogFile,"%s%s : %sn",SoftFault ? "SOFT: " : "HARD: ",PcLine,VaLine);
- }
- else {
- fprintf(LogFile,"%8dt%st%st%st%ut%st%st%un",
- cPfCnt,
- SoftFault ? "SOFT" : "HARD",
- PcModuleStr,
- PcLine,
- (DWORD) Pc,
- VaModuleStr,
- VaLine,
- (DWORD) Va);
- }
- }
- DidOne = TRUE;
- cPfCnt++;
- }
- }
- i++;
- }
- if ( DidOne ) {
- if ( !fLogOnly && !fDatabase) {
- fprintf(stdout,"n");
- }
- }
- //If the buffer overflowed then a non-zero value for
- //the Va was stored in the last record.
- if ((ULONG)WorkingSetBuffer[i].FaultingVa)
- fprintf(stdout,"Warning: Page fault buffer has overflowedn");
- }
- }