📄 profiler.c
字号:
} } } KCALLPROFOFF(74); return TRUE;}#endif // CELOG//------------------------------------------------------------------------------//------------------------------------------------------------------------------//// The following functions are used for GetThreadName.////------------------------------------------------------------------------------//------------------------------------------------------------------------------// Return values from GetModulePointer#define MODULEPOINTER_ERROR 0#define MODULEPOINTER_NK 1#define MODULEPOINTER_DLL 2#define MODULEPOINTER_PROC 4//------------------------------------------------------------------------------//------------------------------------------------------------------------------static DWORDGetModulePointer( PTHREAD pth, unsigned int pc, DWORD* dwResult ) { if (!dwResult) { return MODULEPOINTER_ERROR; } *dwResult = (DWORD) NULL; if (pc & 0x80000000) { // // NK.EXE // return MODULEPOINTER_NK; } else if (pc > (DWORD) DllLoadBase && pc < 0x02000000) { // // It's a DLL address // PMODULE pModMax = NULL, pModTrav = NULL; DWORD dwMax = 0; // // Scan the modules list looking for a module with the highest base // pointer that's less than the PC // pModTrav = pModList; while (pModTrav) { DWORD dwBase = ZeroPtr(pModTrav->BasePtr); if (dwBase > dwMax && dwBase < pc) { dwMax = dwBase; pModMax = pModTrav; } pModTrav = pModTrav->pMod; // Next module. } if (pModMax != NULL) { if (pModMax->oe.filetype == FT_ROMIMAGE) { *dwResult = (DWORD) pModMax; return MODULEPOINTER_DLL; } } } else { // // We assume it's a process // if (pth->pOwnerProc->oe.filetype == FT_ROMIMAGE) { *dwResult = (DWORD) (pth->pOwnerProc); return MODULEPOINTER_PROC; } } return (MODULEPOINTER_ERROR);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------static TOCentry*GetTocPointer( PTHREAD pth, unsigned int pc ) { TOCentry* tocptr = NULL; DWORD dwModulePointer = (DWORD) NULL; DWORD dwMPFlag = GetModulePointer(pth, pc, &dwModulePointer); switch (dwMPFlag) { case MODULEPOINTER_NK: { // nk.exe: tocptr-> first entry in ROM tocptr=(TOCentry *)(pTOC+1); break; } case MODULEPOINTER_DLL: { PMODULE pMod = (PMODULE) dwModulePointer; tocptr = pMod->oe.tocptr; break; } case MODULEPOINTER_PROC: { PPROCESS pProc = (PPROCESS) dwModulePointer; tocptr = pProc->oe.tocptr; break; } default: { // Error tocptr = NULL; } } return (tocptr);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------static HANDLEGetModHandle( PTHREAD pth, unsigned int pc ) { HANDLE hModule; DWORD dwModulePointer = (DWORD) NULL; DWORD dwMPFlag = GetModulePointer(pth, pc, &dwModulePointer); switch (dwMPFlag) { case MODULEPOINTER_NK: { // nk.exe is always the first process hModule = (HANDLE) ProcArray[0].hProc; break; } case MODULEPOINTER_DLL: { // A DLL doesn't have a handle, so return the pointer. hModule = (HANDLE) dwModulePointer; break; } case MODULEPOINTER_PROC: { hModule = (HANDLE) dwModulePointer; break; } default: { // Error hModule = INVALID_HANDLE_VALUE; } } return (hModule);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------LPCSTRGetModName( PTHREAD pth, unsigned int pc ) { LPCSTR pszModName = NULL; TOCentry* tocptr; tocptr = GetTocPointer(pth, pc); if (tocptr != NULL) { pszModName = tocptr->lpszFileName; } return (pszModName);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------// Note: this was called GetSymbol but that didn't want to compile...static LPBYTEGetFuncSymbol(LPBYTE lpSym, DWORD dwSymNum){ while (dwSymNum > 0) { while (*lpSym++); dwSymNum--; } return lpSym;}//------------------------------------------------------------------------------//------------------------------------------------------------------------------LPCSTRGetFunctionName( PTHREAD pth, unsigned int pc ) { LPCSTR pszFunctionName = NULL; TOCentry *tocptr; // table of contents entry pointer PROFentry *profptr=NULL; // profile entry pointer SYMentry *symptr; // profiler symbol entry pointer unsigned int iMod; // module enty in TOC unsigned int iSym; // symbol counter if (!pTOC->ulProfileOffset) { // // No symbols available. // return (NULL); } if (pc & 0x80000000) { // // These addresses belong to NK.EXE. // if (pc >= 0xA0000000) { // // Hit a PSL exception address or perhaps a KDATA routine. No name. // return (NULL); } // // Mask off the caching bit. // pc &= 0xdfffffff; } // // Find the TOC entry if one exists. If not in ROM, then we can't get a name. // tocptr = GetTocPointer(pth, pc); if (tocptr == NULL) { return (NULL); } // // Compute the module number // iMod= ((DWORD)tocptr - (DWORD)(pTOC+1)) / sizeof(TOCentry); // // make profptr point to entry for this module // profptr = (PROFentry *)pTOC->ulProfileOffset; profptr += iMod; // // If there are any symbols in this module, scan for the function. // if (profptr->ulNumSym) { unsigned int iClosestSym; // index of nearest symbol entry SYMentry* pClosestSym; // ptr to nearest symbol entry iSym = 0; symptr=(SYMentry*)profptr->ulHitAddress; iClosestSym = iSym; pClosestSym = symptr; // // Scan the whole list of symbols, looking for the closest match. // while ((iSym < profptr->ulNumSym) && (pClosestSym->ulFuncAddress != pc)) { // Keep track of the closest symbol found if ((symptr->ulFuncAddress <= pc) && (symptr->ulFuncAddress > pClosestSym->ulFuncAddress)) { iClosestSym = iSym; pClosestSym = symptr; } iSym++; symptr++; } pszFunctionName = (LPCSTR) GetFuncSymbol((LPBYTE) profptr->ulSymAddress, iClosestSym); } return (pszFunctionName);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------voidGetThreadName( PTHREAD pth, HANDLE* hModule, WCHAR* szThreadFunctionName ){ DWORD dwProgramCounter = 0; // // Return a pointer to the thread's name if available. // if (pth != NULL) { // The thread's program counter is saved off when it is created. dwProgramCounter = pth->dwStartAddr; if (hModule != NULL) { *hModule = GetModHandle(pth, dwProgramCounter); } if (szThreadFunctionName != NULL) { if (dwProgramCounter == (DWORD) CreateNewProc) { // // Creating a new process, so use the proc name instead of the func // LPSTR lpszTemp; // First try to use the TOC to get the process name if (pth->pOwnerProc && (pth->pOwnerProc->oe.filetype == FT_ROMIMAGE) && (pth->pOwnerProc->oe.tocptr) && (lpszTemp = pth->pOwnerProc->oe.tocptr->lpszFileName)) { KAsciiToUnicode(szThreadFunctionName, lpszTemp, MAX_PATH); } else if (!InSysCall()) { // If we are not inside a KCall we can use the proc struct LPWSTR lpszTempW; if (pth->pOwnerProc && (lpszTempW = pth->pOwnerProc->lpszProcName)) { DWORD dwLen = strlenW(lpszTempW) + 1; memcpy(szThreadFunctionName, lpszTempW, dwLen * sizeof(WCHAR)); } else { szThreadFunctionName[0] = 0; } } else { // Otherwise we have no way to get the thread's name szThreadFunctionName[0] = 0; } } else { // // Look up the function name // LPSTR lpszTemp = (LPSTR) GetFunctionName(pth, dwProgramCounter); if (lpszTemp) { KAsciiToUnicode(szThreadFunctionName, lpszTemp, MAX_PATH); } else { szThreadFunctionName[0] = 0; } } } } else { if (hModule != NULL) { *hModule = INVALID_HANDLE_VALUE; } if (szThreadFunctionName != NULL) { szThreadFunctionName[0] = 0; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -