Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1058 lines
30 KiB

#ifndef KERNRATE_H_INCLUDED
#define KERNRATE_H_INCLUDED
/*++
Copyright (c) 1989-2002 Microsoft Corporation
--*/
//
// set the debug environment
//
#if DBG // NTBE environment
#if NDEBUG
#undef NDEBUG // <assert.h>: assert() is defined
#endif // NDEBUG
#define _DEBUG // <crtdbg.h>: _ASSERT(), _ASSERTE() are defined.
#define DEBUG 1 // our internal file debug flag
#elif _DEBUG // VC++ environment
#ifndef NEBUG
#define NDEBUG
#endif // !NDEBUG
#define DEBUG 1 // our internal file debug flag
#endif
//
// Include System Header files
//
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <dbghelp.h> //The debugger team recommends using dbghelp.h rather than imagehlp.h
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <search.h>
#include <string.h>
#include <memory.h>
#include <ctype.h>
//MC
#include <wchar.h>
//MC
#include <..\pperf\pstat.h>
#include ".\kernrate.rc"
//
// Constant Definitions
//
#define DEFAULT_ZOOM_BUCKET_SIZE 16 //Minimum is 4 bytes
#define DEFAULT_LOG2_ZOOM_BUCKET 4
#define MINIMUM_ZOOM_BUCKET_SIZE 4
#define DEFAULT_SOURCE_CHANGE_INTERVAL 1000 //ms
#define KRATE_DEFAULT_TIMESOURCE_RATE 25000 //Events/Hit
#define DEFAULT_SLEEP_INTERVAL 0
#define MAX_SYMNAME_SIZE 1024
#define USER_SYMPATH_LENGTH 512 //specified on the command line
#define TOTAL_SYMPATH_LENGTH 1024
#define SYM_VALUES_BUF_SIZE 160
#define SYM_KERNEL_HANDLE (HANDLE)-1
#define SYSTEM_PROCESS_NAME "System"
#define TITLE_SIZE 64
#define PROCESS_NAME_SIZE 36 //without extension
#define EXT_SIZE 4 //.exe
#define PROCESS_SIZE (PROCESS_NAME_SIZE+EXT_SIZE+1)
#define DEFAULT_MAX_TASKS 256
#define MAX_PROC_SAME_NAME 8
#define INITIAL_STEP 2 //Symbol enumeration default address stepping
#define JIT_MAX_INITIAL_STEP 16 //Managed Code symbol enumeration maximum step size (bytes)
#define LOCK_CONTENTION_MIN_COUNT 1000
#define MIN_HITS_TO_DISPLAY 1
#define SECONDS_TO_DELAY_PROFILE 0
#define SECONDS_TO_WAIT_CREATED_PROC 2
#define UINT64_MAXDWORD ((unsigned __int64)0xffffffff)
#define DEFAULT_TOKEN_MAX_LENGTH 12 // strlen("dcacheacces")
#define DEFAULT_DESCRIPTION_MAX_LENGTH 25 // strlen("Load Linked Instructions")
#define MAX_DIGITS_IN_INPUT_STRING 9 // Max. allowed digits considered valid input for a number on the command line
#if defined(_IA64_)|| defined(_AMD64_)
#define MAX_SIMULTANEOUS_SOURCES 4
#else
#define MAX_SIMULTANEOUS_SOURCES 1
#endif
#if defined(DISASM_AVAILABLE)
#undefine(DISASM_AVAILABLE)
#endif
//MC
#define MANAGED_CODE_MAINLIB "mscoree.dll" // Presence of which indicates need to handle Managed Code
#define MANAGED_CODE_SYMHLPLIB "ip2md.dll" // Symbol translation helper library for Managed Code
//MC
//
// Macros
//
#define WIN2K_OS (gOSInfo.dwMajorVersion == 5 && gOSInfo.dwMinorVersion == 0)
#define FPRINTF (void)fprintf
#define RATE_DATA_FIXED_SIZE (5*sizeof(ULONGLONG))
#define RATE_DATA_VAR_SIZE ((sizeof(ULONGLONG *)+sizeof(HANDLE *)+sizeof(ULONG *)+sizeof(PULONG *))*gProfileProcessors)
#define BUCKETS_NEEDED(length) ( length%gZoomBucket == 0? (length/gZoomBucket):(1+length/gZoomBucket) )
#define MODULE_SIZE (sizeof(MODULE)+(RATE_DATA_FIXED_SIZE + RATE_DATA_VAR_SIZE)*gSourceMaximum)
#define IsValidHandle( _Hdl ) ( ( (_Hdl) != (HANDLE)0 ) && ( (_Hdl) != INVALID_HANDLE_VALUE ) )
#define VerbosePrint( _x_ ) vVerbosePrint _x_
#define ModuleFileName( _Module ) \
( (_Module)->module_FileName ? (_Module)->module_FileName : (_Module)->module_Name )
#define ModuleFullName( _Module ) \
( (_Module)->module_FullName ? (_Module)->module_FullName : ModuleFileName( _Module ) )
//
// On Itanium it turns out that you may request a rate of let's say 800 but actually get 799...
// The check for an exact match in this case will fail and the logic will force the default rate
// The following allows a tollerance of 25 percent to be considered as a match
//
#define PERCENT_DIFF(a,b) ( a > b? (100*(a-b))/b : (100*(b-a))/b )
#define RATES_MATCH(a,b) ( PERCENT_DIFF(a,b) <= 25 )
//
// Struct and Enum Type Definitions and Related Globals
//
typedef enum _KERNRATE_NAMESPACE {
cMAPANDLOAD_READONLY = TRUE,
cDONOT_ALLOCATE_DESTINATION_STRING = FALSE,
} eKERNRATE_NAMESPACE;
typedef enum _ACTION_TYPE {
START = 0,
STOP = 1,
OUTPUT = 2,
DEFAULT= 3
} ACTION_TYPE;
//
// Verbose Output Related
//
typedef enum _VERBOSE_ENUM {
VERBOSE_NONE = 0, //
VERBOSE_IMAGEHLP = 0x1, //
VERBOSE_PROFILING = 0x2, //
VERBOSE_INTERNALS = 0x4, //
VERBOSE_MODULES = 0x8, //
VERBOSE_DEFAULT = VERBOSE_IMAGEHLP,
VERBOSE_MAX = VERBOSE_IMAGEHLP | VERBOSE_PROFILING | VERBOSE_INTERNALS | VERBOSE_MODULES
} VERBOSE_ENUM;
typedef struct _VERBOSE_DEFINITION {
VERBOSE_ENUM VerboseEnum;
const char * const VerboseString;
} VERBOSE_DEFINITION, *PVERBOSE_DEFINITION;
//
// Profile Source Related
//
typedef struct _SOURCE {
PCHAR Name; // pstat EVENTID.Description
KPROFILE_SOURCE ProfileSource;
PCHAR ShortName; // pstat EVENTID.ShortName
ULONG DesiredInterval; // system default interval
ULONG Interval; // user set interval (not guaranteed)
BOOL bProfileStarted;
} SOURCE, *PSOURCE;
typedef struct _RATE_DATA {
ULONGLONG StartTime;
ULONGLONG TotalTime;
ULONGLONG Rate; // Events/Second
ULONGLONG GrandTotalCount;
ULONGLONG DoubtfulCounts;
ULONGLONG *TotalCount;
HANDLE *ProfileHandle;
ULONG *CurrentCount;
PULONG *ProfileBuffer;
} RATE_DATA, *PRATE_DATA;
//
// Module related definitions
//
typedef enum _MODULE_NAMESPACE {
cMODULE_NAME_STRLEN = 132, // maximum module name, including '\0'
} eMODULE_NAMESPACE;
typedef struct _MODULE {
struct _MODULE *Next;
HANDLE hProcess;
ULONG64 Base;
ULONG Length;
BOOL bZoom;
union {
BOOL bProfileStarted;
BOOL bHasHits;
} mu;
CHAR module_Name[cMODULE_NAME_STRLEN]; // filename w/o its extension
PCHAR module_FileName; // filename with its extension
PCHAR module_FullName; // full pathname
RATE_DATA Rate[];
} MODULE, *PMODULE;
typedef struct _RATE_SUMMARY {
ULONGLONG TotalCount;
PMODULE *Modules;
ULONG ModuleCount;
} RATE_SUMMARY, *PRATE_SUMMARY;
//
// Process related definitions
//
typedef struct _PROC_PERF_INFO {
ULONG NumberOfThreads;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
SIZE_T VirtualSize;
ULONG HandleCount;
ULONG PageFaultCount;
SIZE_T WorkingSetSize;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
// If ever needed the following can be added
// SIZE_T PeakVirtualSize;
// SIZE_T PeakWorkingSetSize;
// SIZE_T QuotaPeakPagedPoolUsage;
// SIZE_T QuotaPeakNonPagedPoolUsage;
} PROC_PERF_INFO, *PPROC_PERF_INFO;
typedef struct _PROC_TO_MONITOR {
struct _PROC_TO_MONITOR *Next;
HANDLE ProcessHandle;
LONGLONG Pid;
ULONG Index;
PCHAR ProcessName;
ULONG ModuleCount;
ULONG ZoomCount;
PMODULE ModuleList;
PMODULE ZoomList;
PSOURCE Source;
PROC_PERF_INFO ProcPerfInfoStart;
PSYSTEM_THREAD_INFORMATION pProcThreadInfoStart;
PRTL_DEBUG_INFORMATION pProcDebugInfoStart;
PRTL_DEBUG_INFORMATION pProcDebugInfoStop;
//MC
DWORD *JITHeapLocationsStart;
DWORD *JITHeapLocationsStop;
//MC
} PROC_TO_MONITOR, *PPROC_TO_MONITOR;
//
// These processor level enums should be defined in public headers.
// ntexapi.h - NtQuerySystemInformation( SystemProcessorInformation).
//
// For Now Define them locally.
//
typedef enum _PROCESSOR_FAMILY {
IA64_FAMILY_MERCED = 0x7,
IA64_FAMILY_ITANIUM = IA64_FAMILY_MERCED,
IA64_FAMILY_MCKINLEY = 0x1f
} PROCESSOR_FAMILY;
#if defined(_IA64_)
#if 0
#define IA64ProcessorLevel2ProcessorFamily( (_ProcessorLevel >> 8) & 0xff )
#else
//
// BUGBUG - Thierry - 02/20/2002
// Fix until SYSTEM_PROCESSOR_INFORMATION is fixed in the OS.
//
#ifndef CV_IA64_CPUID3
#define CV_IA64_CPUID3 3331
#endif
__inline USHORT
IA64ProcessorLevel2ProcessorFamily(
USHORT ProcessorLevel
)
{
return( (USHORT)((__getReg(CV_IA64_CPUID3) >> 24) & 0xff));
}
#endif
#endif // _IA64_
//
// The Following is Defined in pstat.h but not for Win2K
// The definition below allows for single source management for Win2K and above
//
#ifndef PSTAT_QUERY_EVENTS_INFO
#define PSTAT_QUERY_EVENTS_INFO CTL_CODE (FILE_DEVICE_UNKNOWN, 5, METHOD_NEITHER, FILE_ANY_ACCESS)
typedef struct _EVENTS_INFO {
ULONG Events;
ULONG TokenMaxLength;
ULONG DescriptionMaxLength;
ULONG OfficialTokenMaxLength;
ULONG OfficialDescriptionMaxLength;
} EVENTS_INFO, *PEVENTS_INFO;
#endif
#ifndef RTL_QUERY_PROCESS_NONINVASIVE
#define RTL_QUERY_PROCESS_NONINVASIVE 0x80000000
#endif
//
//
//
typedef struct _TASK_LIST {
LONGLONG ProcessId;
CHAR ProcessName[PROCESS_SIZE];
PSYSTEM_THREAD_INFORMATION pProcessThreadInfo;
PROC_PERF_INFO ProcessPerfInfo;
} TASK_LIST, *PTASK_LIST;
typedef struct _TASK_LIST_ENUM {
PTASK_LIST tlist;
ULONG numtasks;
} TASK_LIST_ENUM, *PTASK_LIST_ENUM;
typedef struct _uint64div {
unsigned __int64 quot;
unsigned __int64 rem;
} uint64div_t;
typedef struct _int64div {
__int64 quot;
__int64 rem;
} int64div_t;
typedef struct _InputCount {
UCHAR InputOption;
SHORT Allowed;
SHORT ActualCount;
} InputCount;
//
// Globals
//
//
static CHAR gUserSymbolPath[USER_SYMPATH_LENGTH];
static CHAR gSymbolPath[TOTAL_SYMPATH_LENGTH];
static DWORD gSymOptions;
PIMAGEHLP_SYMBOL64 gSymbol;
BOOL bSymPathInitialized = FALSE;
//
static PMODULE gCurrentModule = (PMODULE)0;
PMODULE gCallbackCurrent;
ULONG gZoomCount;
//
PSYSTEM_BASIC_INFORMATION gSysBasicInfo;
LONG gProfileProcessors; //Actual being profiled
KAFFINITY gAffinityMask = 0; //Processor Afinity Mask for selected processor profiling
ULONG gMaxSimultaneousSources; //Maximum allowed number of sources that can be turned on simultaneously
CHAR gSystemProcessName[] = SYSTEM_PROCESS_NAME;
OSVERSIONINFO gOSInfo;
HANDLE ghDoneEvent;
BOOL gProfilingDone = FALSE;
//
ULONG gNumProcToMonitor = 0; //Total Number of Processes To Monitor
ULONG gKernelModuleCount = 0;
PPROC_TO_MONITOR gProcessList = NULL;
PPROC_TO_MONITOR gpProcDummy;
PPROC_TO_MONITOR gpSysProc = NULL;
PMODULE gCommonZoomList = NULL; //List of Zoom Modules Common to More Than One Process such as ntdll
//
long double gldElapsedSeconds;
ULONG gTotalElapsedSeconds; // Sum On All Processors
LARGE_INTEGER gTotalElapsedTime64;
LARGE_INTEGER gTotal2ElapsedTime64;
//
ULONG gZoomBucket = DEFAULT_ZOOM_BUCKET_SIZE;
ULONG gLog2ZoomBucket = DEFAULT_LOG2_ZOOM_BUCKET;
ULONG gSourceMaximum = 0;
ULONG gStaticCount = 0;
ULONG gTotalActiveSources = 0;
PSOURCE gStaticSource = NULL;
//
ULONG gNumTasksStart;
ULONG gNumTasksStop;
PTASK_LIST gTlistStart;
double gTotalIdleTime = 0;
//MC
BOOL bMCHelperLoaded = FALSE; //Is Managed Code Helper Library Loaded
BOOL bMCJitRangesExist = FALSE; //Were any JIT ranges found
BOOL bImageHlpSymbolFound = FALSE; //SymEnumerateSymbols64 found at least one symbol
HANDLE ghMCLib = NULL; //Handle to MC helper IP2MC.DLL
WCHAR* gwszSymbol;
//MC
//
// Print format for event strings
//
ULONG gTokenMaxLen = DEFAULT_TOKEN_MAX_LENGTH;
ULONG gDescriptionMaxLen = DEFAULT_DESCRIPTION_MAX_LENGTH;
//
//Verbose Output related
//
VERBOSE_DEFINITION VerboseDefinition[] = {
{ VERBOSE_NONE, "None" },
{ VERBOSE_IMAGEHLP, "Displays ImageHlp Operations" },
{ VERBOSE_PROFILING, "Displays Profiling Operations and Per Bucket Information Including Symbol Verification" },
{ VERBOSE_INTERNALS, "Displays Internals Operations" },
{ VERBOSE_MODULES, "Displays Modules Operations" },
{ VERBOSE_NONE, NULL }
};
ULONG gVerbose = VERBOSE_NONE;
BOOL bRoundingVerboseOutput = FALSE;
//
// User command-line input related
//
typedef enum _INPUT_ERROR_TYPE {
INPUT_GOOD = 1,
UNKNOWN_OPTION,
BOGUS_ENTRY,
MISSING_PARAMETER,
MISSING_NUMBER,
MISSING_REQUIRED_NUMBER,
MISSING_STRING,
MISSING_REQUIRED_STRING,
INVALID_NUMBER
} INPUT_ERROR_TYPE;
typedef enum _INPUT_ORDER {
ORDER_ANY,
ORDER_STRING_FIRST,
ORDER_NUMBER_FIRST
} INPUT_ORDER;
typedef enum _INPUT_OPTIONAL {
OPTIONAL_ANY,
OPTIONAL_STRING,
OPTIONAL_NUMBER,
OPTIONAL_NONE,
} INPUT_OPTIONAL;
BOOL bCombinedProfile = FALSE; // Do Both Kernel and User Process(es)
LONG gChangeInterval = DEFAULT_SOURCE_CHANGE_INTERVAL;
BOOL bWaitForUserInput = FALSE; // Wait for the user to press a key before starting the profile
BOOL bWaitCreatedProcToSettle = FALSE; // Indication that one or more processes were created via the -o option
BOOL bCreatedProcWaitForUserInput = FALSE; // Wait for the user to press a key to indicate a created process has settled (gone idle)
LONG gSecondsToDelayProfile = SECONDS_TO_DELAY_PROFILE; // Wait for N seconds before starting the profile
LONG gSecondsToWaitCreatedProc = SECONDS_TO_WAIT_CREATED_PROC; // Wait for N seconds for a created process to settle (go idle)
LONG gSleepInterval = DEFAULT_SLEEP_INTERVAL; //Used to set the profile period
BOOL bRawData = FALSE;
BOOL bRawDisasm = FALSE;
BOOL bProfileByProcessor = FALSE;
BOOL bGetInterestingData = FALSE; // Get Interesting statistics (turns on several sources, depends on hits, not guaratied)
BOOL bOldSampling = FALSE; // Use new sampling scheme (start all sources and let them run simultaneously)
BOOL bIncludeGeneralInfo = TRUE; // Include system-wide and process-specific information (such as context switches, memory usage, etc.)
BOOL bDisplayTaskSummary = FALSE;
ULONG gMaxTasks = DEFAULT_MAX_TASKS; //Max Number of tasks accomodated in Kernrate's Task List
BOOL bIncludeSystemLocksInfo = FALSE; // Get System lock contention info
BOOL bIncludeUserProcLocksInfo= FALSE; // Get User process lock contention info
ULONG gLockContentionMinCount = LOCK_CONTENTION_MIN_COUNT; // Default minimum count of lock contention for output processing
ULONG gMinHitsToDisplay = MIN_HITS_TO_DISPLAY;
BOOL bProcessDataHighPriority = FALSE; // User may opt to finish processing the collected data at high priority
// This is useful on a very busy system if the momentary overhead is not an issue
BOOL bSystemThreadsInfo = FALSE; // System-Process (kernel mode) threads
BOOL bIncludeThreadsInfo = FALSE; // Get thread info (it will then be gathered for all running tasks)
HANDLE ghInput = NULL, ghOutput = NULL, ghError = NULL;
//
// Most Static Sources desired intervals are computed to give approximately
// one interrupt per millisecond and be a nice even power of 2
//
enum _STATIC_SOURCE_TYPE {
SOURCE_TIME = 0,
};
// The following are defined in several headers,
// were supported on ALPHA, but they currently have no x86 KE/HAL support except for Time and AlignFixup
// Merced.c and Mckinley.c define the supported static sources on IA64 Merced/McKinley systems
// Amd64.c defines the supported static sources on Amd64 systems
SOURCE StaticSources[] = {
{"Time", ProfileTime, "time" , 1000, KRATE_DEFAULT_TIMESOURCE_RATE},
{"Alignment Fixup", ProfileAlignmentFixup, "alignfixup" , 1,0},
{"Total Issues", ProfileTotalIssues, "totalissues", 131072,0},
{"Pipeline Dry", ProfilePipelineDry, "pipelinedry", 131072,0},
{"Load Instructions", ProfileLoadInstructions, "loadinst" , 65536,0},
{"Pipeline Frozen", ProfilePipelineFrozen, "pilelinefrz", 131072,0},
{"Branch Instructions", ProfileBranchInstructions, "branchinst" , 65536,0},
{"Total Nonissues", ProfileTotalNonissues, "totalnoniss", 131072,0},
{"Dcache Misses", ProfileDcacheMisses, "dcachemiss" , 16384,0},
{"Icache Misses", ProfileIcacheMisses, "icachemiss" , 16384,0},
{"Cache Misses", ProfileCacheMisses, "cachemiss" , 16384,0},
{"Branch Mispredictions", ProfileBranchMispredictions, "branchpred" , 16384,0},
{"Store Instructions", ProfileStoreInstructions, "storeinst" , 65536,0},
{"Floating Point Instr", ProfileFpInstructions, "fpinst" , 65536,0},
{"Integer Instructions", ProfileIntegerInstructions, "intinst" , 65536,0},
{"Dual Issues", Profile2Issue, "2issue" , 65536,0},
{"Triple Issues", Profile3Issue, "3issue" , 16384,0},
{"Quad Issues", Profile4Issue, "4issue" , 16384,0},
{"Special Instructions", ProfileSpecialInstructions, "specinst" , 16384,0},
{"Cycles", ProfileTotalCycles, "totalcycles", 655360,0},
{"Icache Issues", ProfileIcacheIssues, "icacheissue", 65536,0},
{"Dcache Accesses", ProfileDcacheAccesses, "dcacheacces", 65536,0},
{"MB Stall Cycles", ProfileMemoryBarrierCycles, "membarcycle", 32767,0},
{"Load Linked Instructions", ProfileLoadLinkedIssues, "loadlinkiss", 16384,0},
{NULL, ProfileMaximum, "", 0, 0}
};
#if defined(_IA64_)
#include "merced.c"
#include "mckinley.c"
#endif // _IA64_
#if defined(_AMD64_)
#include "amd64.c"
#endif // _AMD64_
//
// "Interesting Data" constituents
//
KPROFILE_SOURCE IData[] = {
#if defined(_IA64_)
ProfileTotalIssues, //This source must always be first in the array
ProfileLoadInstructions,
ProfileStoreInstructions,
ProfileBranchInstructions,
ProfileFpInstructions,
ProfileIntegerInstructions,
ProfileCacheMisses,
ProfileIcacheMisses,
ProfileDcacheMisses,
ProfileBranchMispredictions,
ProfileTotalCycles
#elif defined(_AMD64_)
ProfileTotalIssues,
ProfileBranchInstructions,
ProfileFpInstructions,
ProfileIcacheMisses,
ProfileDcacheMisses,
ProfileBranchMispredictions
#else
ProfileTotalIssues
#endif
};
PULONG gulActiveSources;
//
// For checking command line input options for unallowed duplicates
// (0=no such option, -1=unlimited, -2 don't care)
//
InputCount InputOption[] = {
{ 'A', 1, 0 },
{ 'B', 1, 0 },
{ 'C', 1, 0 },
{ 'D',-2, 0 },
{ 'E',-2, 0 },
{ 'F',-2, 0 },
{ 'G', 1, 0 },
{ 'H',-2, 0 },
{ 'I',-1, 0 },
{ 'J', 1, 0 },
{ 'K', 1, 0 },
{ 'L', 1, 0 },
{ 'M', 1, 0 },
{ 'N',-1, 0 },
{ 'O',-1, 0 },
{ 'P',-1, 0 },
{ 'Q', 0, 0 },
{ 'R',-2, 0 },
{ 'S', 1, 0 },
{ 'T', 1, 0 },
{ 'U',-2, 0 },
{ 'V',-1, 0 },
{ 'W', 2, 0 },
{ 'X', 1, 0 },
{ 'Y', 0, 0 },
{ 'Z',-1, 0 }
};
InputCount wCount = {'W', 1, 0};
InputCount wpCount = {'W', 1, 0};
//
// Function prototypes
//
VOID
CleanZoomModuleList(
PPROC_TO_MONITOR Proc
);
VOID
CreateDoneEvent(
VOID
);
//MC
BOOL
CreateJITZoomModuleCallback(
IN PWCHAR wszSymName,
IN LPSTR szSymName,
IN ULONG64 Address,
IN ULONG Size,
IN PVOID Cxt
);
//MC
PMODULE
CreateNewModule(
IN PPROC_TO_MONITOR ProcToMonitor,
IN PCHAR ModuleName,
IN PCHAR ModuleFullName,
IN ULONG64 ImageBase,
IN ULONG ImageSize
);
VOID
CreateProfiles(
IN PMODULE Root,
IN PPROC_TO_MONITOR ProcToMonitor
);
VOID
CreateZoomedModuleList(
IN PMODULE ZoomModule,
IN ULONG RoundDown,
IN PPROC_TO_MONITOR pProc
);
BOOL
CreateZoomModuleCallback(
IN LPSTR szSymName,
IN ULONG64 Address,
IN ULONG Size,
IN PVOID Cxt
);
VOID
DisplayRunningTasksSummary (
PTASK_LIST pTaskStart,
PTASK_LIST pTaskStop
);
VOID
DisplaySystemWideInformation(
PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemInfoBegin,
PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemInfoEnd
);
VOID
DisplayTotalAndRate (
LONGLONG StartCount,
LONGLONG StopCount,
long double RateAgainst,
PCHAR CounterName,
PCHAR RateAgainstUnits
);
BOOL
EnumerateSymbolsByBuckets(
IN HANDLE SymHandle,
IN PMODULE Current,
IN PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,
IN PVOID pProc
);
VOID
ExecuteProfiles(
BOOL bMode
);
VOID
ExitWithMissingEntryMessage(
PCHAR CurrentOption,
PCHAR Remark,
BOOL bUsage
);
VOID
ExitWithUnknownOptionMessage(
PCHAR CurrentOption
);
PMODULE
FindModuleForAddress64(
PPROC_TO_MONITOR ProcToMonitor,
DWORD64 Address
);
VOID
GetConfiguration(
int argc,
char *argv[]
);
PMODULE
GetKernelModuleInformation(
VOID
);
VOID
GetProcessLocksInformation (
PPROC_TO_MONITOR ProcToMonitor,
ULONG Flags,
ACTION_TYPE Action
);
PMODULE
GetProcessModuleInformation(
IN PPROC_TO_MONITOR ProcToMonitor
);
VOID
GetProfileSystemInfo(
ACTION_TYPE Action
);
PSYSTEM_BASIC_INFORMATION
GetSystemBasicInformation(
VOID
);
VOID
GetSystemLocksInformation (
ACTION_TYPE Action
);
DWORD
GetTaskList(
PTASK_LIST pTask,
ULONG NumTasks
);
ULONG
HandleRedirections(
IN PCHAR cmdLine,
IN ULONG nCharsStart,
OUT HANDLE *hInput,
OUT HANDLE *hOutput,
OUT HANDLE *hError
);
BOOL
HitsFound(
IN PPROC_TO_MONITOR pProc,
IN ULONG BucketIndex
);
VOID
InitAllProcessesModulesInfo(
VOID
);
BOOL
InitializeAsDebugger(VOID);
BOOL
InitializeKernelProfile(VOID);
VOID
InitializeKernrate(
int argc,
char *argv[]
);
PPROC_TO_MONITOR
InitializeProcToMonitor(
LONGLONG Pid
);
ULONG
InitializeProfileSourceInfo (
PPROC_TO_MONITOR ProcToMonitor
);
VOID
InitSymbolPath(
HANDLE SymHandle
);
VOID
InvalidEntryMessage(
PCHAR CurrentOption,
PCHAR CurrentValue,
PCHAR Remark,
BOOL bUsage,
BOOL bExit
);
INPUT_ERROR_TYPE
IsInputValid(int argc,
int OptionIndex,
PCHAR *Option,
PCHAR AllowedTrailLetters,
PLONG AssociatedNumber,
PCHAR AssociatedString,
ULONG MaxStringLength,
INPUT_ORDER Order,
INPUT_OPTIONAL Optional
);
BOOL
IsStringANumber(
IN PCHAR String
);
ULONG
NextSource(
IN ULONG CurrentSource,
IN PMODULE ModuleList,
IN PPROC_TO_MONITOR ProcToMonitor
);
VOID
OutputInterestingData(
IN FILE *Out,
IN RATE_DATA Data[]
);
VOID
OutputLine(
IN FILE *Out,
IN ULONG ProfileSourceIndex,
IN PMODULE Module,
IN PRATE_SUMMARY RateSummary,
IN PPROC_TO_MONITOR ProcToMonitor
);
VOID
OutputLineFromAddress64(
HANDLE hProc,
DWORD64 qwAddr,
PIMAGEHLP_LINE64 pLine
);
VOID
OutputLocksInformation(
PRTL_PROCESS_LOCKS pLockInfoStart,
PRTL_PROCESS_LOCKS pLockInfoStop,
PPROC_TO_MONITOR Proc
);
VOID
OutputModuleList(
IN FILE *Out,
IN PMODULE ModuleList,
IN ULONG NumberModules,
IN PPROC_TO_MONITOR ProcToMonitor,
IN PMODULE Parent
);
VOID
OutputPercentValue (
LONGLONG StartCount,
LONGLONG StopCount,
LARGE_INTEGER Base,
PCHAR CounterName
);
VOID
OutputProcessPerfInfo (
PTASK_LIST pTask,
ULONG NumTasks,
PPROC_TO_MONITOR ProcToMonitor
);
VOID
OutputRawDataForZoomModule(
IN FILE *Out,
IN PPROC_TO_MONITOR ProcToMonitor,
IN PMODULE Current
);
VOID
OutputResults(
IN FILE *Out,
IN PPROC_TO_MONITOR ProcToMonitor
);
VOID
OutputStartStopValues (
SIZE_T StartCount,
SIZE_T StopCount,
PCHAR CounterName
);
VOID
OutputThreadInfo (
PTASK_LIST pTask,
DWORD TaskNumber,
PPROC_TO_MONITOR ProcToMonitor
);
BOOL
PrivEnumerateSymbols(
IN HANDLE SymHandle,
IN PMODULE Current,
IN PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,
IN PVOID pProc,
IN DWORD64 BaseOptional,
IN ULONG SizeOptional
);
VOID
SetProfileSourcesRates(
PPROC_TO_MONITOR ProcToMonitor
);
VOID
StartSource(
IN ULONG ProfileSource,
IN PMODULE ModuleList,
IN PPROC_TO_MONITOR ProcToMonitor
);
VOID
StopSource(
IN ULONG ProfileSourceIndex,
IN PMODULE ModuleList,
IN PPROC_TO_MONITOR ProcToMonitor
);
BOOL
TkEnumerateSymbols(
IN HANDLE SymHandle,
IN PMODULE Current,
IN PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,
IN PVOID pProc
);
VOID
UpdateProcessStartInfo(
PPROC_TO_MONITOR ProcToMonitor,
PTASK_LIST TaskListEntry,
BOOL bIncludeProcessThreadsInfo
);
VOID
vVerbosePrint(
ULONG Level,
PCCHAR Msg,
...
);
//MC
//
// Note: CLR currently does not support 64 bit.
//
// AttachToProcess is not reentrant, even for different PIDs!
// only call once and pair with DetachFromProcess.
extern void AttachToProcess(DWORD dwPid);
extern void DetachFromProcess();
// 0 is error
// 1 is normal JIT
// 2 is ngen (prejitted module)
// wszResult contains class/method (string) of given IP address
// Note: The space is allocated by the routine itself!
extern int IP2MD(DWORD_PTR test,WCHAR** wszResult);
// return value is array of DWORDs, stored in pairs, null terminated.
// first dword is start address, second dword is length.
extern DWORD* GetJitRange();
typedef void (*PFN1)(DWORD);
PFN1 pfnAttachToProcess;
typedef void (*PFN2)(VOID);
PFN2 pfnDetachFromProcess;
typedef int (*PFN3)(DWORD_PTR, WCHAR**);
PFN3 pfnIP2MD;
typedef DWORD* (*PFN4)(VOID);
PFN4 pfnGetJitRange;
BOOL
InitializeManagedCodeSupport(
PPROC_TO_MONITOR ProcToMonitor
);
BOOL
JITEnumerateSymbols(
IN PMODULE Current,
IN PVOID pProc,
IN DWORD64 BaseOptional,
IN ULONG SizeOptional
);
VOID
OutputJITRangeComparison(
PPROC_TO_MONITOR ProcToMonitor
);
//MC
PCHAR WaitReason [] = {
{"Executive"},
{"FreePage"},
{"PageIn"},
{"PoolAllocation"},
{"DelayExecution"},
{"Suspended"},
{"UserRequest"},
{"WrExecutive"},
{"WrFreePage"},
{"WrPageIn"},
{"WrPoolAllocation"},
{"WrDelayExecution"},
{"WrSuspended"},
{"WrUserRequest"},
{"WrEventPair"},
{"WrQueue"},
{"WrLpcReceive"},
{"WrLpcReply"},
{"WrVirtualMemory"},
{"WrPageOut"},
{"WrRendezvous"},
{"Spare2"},
{"Spare3"},
{"Spare4"},
{"Spare5"},
{"Spare6"},
{"WrKernel"},
{"WrResource"},
{"WrPushLock"},
{"WrMutex"},
{"WrQuantumEnd"},
{"WrDispatchInt"},
{"WrPreempted"},
{"WrYieldExecution"},
{"MaximumWaitReason"}
};
PCHAR ThreadState[] = {
{"Initialized"},
{"Ready"},
{"Running"},
{"Standby"},
{"Terminated"},
{"Waiting"},
{"Transition"},
{"DeferredReady"}
};
#endif /* !KERNRATE_H_INCLUDED */