VOID CpuFuncInsertData( __in HWND hWnd, __in PPF_REPORT_HEAD Head ) { LVITEM lvi = {0}; ULONG i, j; ULONG Count; WCHAR Buffer[MAX_PATH]; HWND hWndCtrl; PBTR_FUNCTION_ENTRY FuncEntry; PBTR_TEXT_TABLE TextTable; PBTR_TEXT_FILE TextFile; PBTR_TEXT_ENTRY TextEntry; PBTR_PC_ENTRY PcEntry; PBTR_LINE_ENTRY LineEntry; PBTR_LINE_ENTRY Line; ULONG Inclusive; ULONG Exclusive; PWSTR Unicode; double Percent; hWndCtrl = GetDlgItem(hWnd, IDC_LIST_FUNCTION); Count = (ULONG)(Head->Streams[STREAM_FUNCTION].Length / sizeof(BTR_FUNCTION_ENTRY)); FuncEntry = (PBTR_FUNCTION_ENTRY)((PUCHAR)Head + Head->Streams[STREAM_FUNCTION].Offset); PcEntry = (PBTR_PC_ENTRY)((PUCHAR)Head + Head->Streams[STREAM_PC].Offset); TextFile = (PBTR_TEXT_FILE)((PUCHAR)Head + Head->Streams[STREAM_SYMBOL].Offset); if (Head->Streams[STREAM_LINE].Offset != 0 && Head->Streams[STREAM_LINE].Length != 0) { Line = (PBTR_LINE_ENTRY)((PUCHAR)Head + Head->Streams[STREAM_LINE].Offset); } else { Line = NULL; } // // Total sample count as initial exclusive/inclusive // ApsGetCpuSampleCounters(Head, &Inclusive, &Exclusive); //Inclusive = Exclusive; TextTable = ApsBuildSymbolTable(TextFile, 4093); for(i = 0, j = 0; i < Count; i++) { Percent = (FuncEntry->Inclusive * 1.0) / (Inclusive * 1.0); if (Percent < CPU_UI_INCLUSIVE_RATIO_THRESHOLD) { FuncEntry += 1; continue; } // // Symbol name // lvi.iItem = j; lvi.iSubItem = 0; lvi.mask = LVIF_TEXT|LVIF_PARAM; lvi.lParam = (LPARAM)FuncEntry; TextEntry = ApsLookupSymbol(TextTable, FuncEntry->Address); ASSERT(TextEntry != NULL); StringCchPrintf(Buffer, MAX_PATH, L"%S", TextEntry->Text); lvi.pszText = Buffer; ListView_InsertItem(hWndCtrl, &lvi); // // Inclusive // lvi.iSubItem = 1; lvi.mask = LVIF_TEXT; StringCchPrintf(Buffer, MAX_PATH, L"%u", FuncEntry->Inclusive); lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); // // Inclusive % // lvi.iSubItem = 2; lvi.mask = LVIF_TEXT; StringCchPrintf(Buffer, MAX_PATH, L"%.2f", (FuncEntry->Inclusive * 100.0) / (Inclusive * 1.0)); lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); // // Exclusive // lvi.iSubItem = 3; lvi.mask = LVIF_TEXT; StringCchPrintf(Buffer, MAX_PATH, L"%u", FuncEntry->Exclusive); lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); // // Exclusive % // lvi.iSubItem = 4; lvi.mask = LVIF_TEXT; StringCchPrintf(Buffer, MAX_PATH, L"%.2f", (FuncEntry->Exclusive * 100.0) / (Exclusive * 1.0)); lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); // // Module // lvi.iSubItem = 5; lvi.mask = LVIF_TEXT; ApsGetDllBaseNameById(Head, FuncEntry->DllId, Buffer, MAX_PATH); lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); // // Line // if (Line != NULL && TextEntry->LineId != -1) { ASSERT(Line != NULL); LineEntry = Line + TextEntry->LineId; StringCchPrintf(Buffer, MAX_PATH, L"%S:%u", LineEntry->File, LineEntry->Line); lvi.iSubItem = 6; lvi.mask = LVIF_TEXT; lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); } else { lvi.iSubItem = 6; lvi.mask = LVIF_TEXT; lvi.pszText = L""; ListView_SetItem(hWndCtrl, &lvi); } FuncEntry += 1; j += 1; } ApsDestroySymbolTable(TextTable); Unicode = (PWSTR)ApsMalloc(MAX_PATH * 2); StringCchPrintf(Unicode, MAX_PATH, L"Total %u Function samples", Count); PostMessage(GetParent(hWnd), WM_USER_STATUSBAR, 0, (LPARAM)Unicode); }
LRESULT CpuThreadOnItemChanged( __in PDIALOG_OBJECT Object, __in NMLISTVIEW *lpNmlv ) { PCPU_THREAD Thread; PCPU_THREAD_PC_TABLE PcTable; HWND hWndCtrl; LVITEM lvi = {0}; WCHAR Buffer[MAX_PATH]; PBTR_TEXT_TABLE TextTable; PBTR_TEXT_FILE TextFile; PBTR_TEXT_ENTRY TextEntry; PCPU_THREAD_PC PcEntry; ULONG Exclusive; PPF_REPORT_HEAD Head; PCPU_FORM_CONTEXT Form; ULONG i; ULONG Number; PBTR_LINE_ENTRY Line; PBTR_LINE_ENTRY LineEntry; PBTR_DLL_FILE DllFile; PBTR_DLL_ENTRY DllEntry; double Percent; Form = (PCPU_FORM_CONTEXT)Object->Context; ASSERT(Form != NULL); Head = Form->Head; ASSERT(Head != NULL); if (lpNmlv->uNewState & LVIS_SELECTED) { // // Delete all items if any // hWndCtrl = GetDlgItem(Object->hWnd, IDC_LIST_CPU_THREAD_PC); ListView_DeleteAllItems(hWndCtrl); ASSERT(lpNmlv->lParam != 0); Thread = (PCPU_THREAD)lpNmlv->lParam; PcTable = Thread->Table; ASSERT(PcTable != NULL); // // Build symbol table to parse PC address // TextFile = (PBTR_TEXT_FILE)((PUCHAR)Head + Head->Streams[STREAM_SYMBOL].Offset); TextTable = ApsBuildSymbolTable(TextFile, 4093); Exclusive = Thread->Exclusive; Number = 0; DllFile = (PBTR_DLL_FILE)ApsGetStreamPointer(Head, STREAM_DLL); DllEntry = &DllFile->Dll[0]; Line = (PBTR_LINE_ENTRY)ApsGetStreamPointer(Head, STREAM_LINE); LineEntry = Line; for(i = 0; i < CPU_PC_BUCKET; i++) { PLIST_ENTRY ListEntry; PLIST_ENTRY ListHead; ListHead = &PcTable->ListHead[i]; ListEntry = ListHead->Flink; while (ListEntry != ListHead) { PcEntry = CONTAINING_RECORD(ListEntry, CPU_THREAD_PC, ListEntry); Percent = (PcEntry->Inclusive * 1.0) / (Exclusive * 1.0); if (Percent < CPU_UI_INCLUSIVE_RATIO_THRESHOLD) { ListEntry = ListEntry->Flink; continue; } // // Symbol name // lvi.iItem = Number; lvi.iSubItem = 0; lvi.mask = LVIF_TEXT|LVIF_PARAM; lvi.lParam = (LPARAM)PcEntry; ASSERT(PcEntry->Pc != NULL); TextEntry = ApsLookupSymbol(TextTable, (ULONG64)PcEntry->Pc); if (TextEntry) { StringCchPrintf(Buffer, MAX_PATH, L"%S", TextEntry->Text); } else { ApsFormatAddress(Buffer, MAX_PATH, PcEntry->Pc, TRUE); } lvi.pszText = Buffer; ListView_InsertItem(hWndCtrl, &lvi); // // Inclusive // lvi.iSubItem = 1; lvi.mask = LVIF_TEXT; StringCchPrintf(Buffer, MAX_PATH, L"%u", PcEntry->Inclusive); lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); // // Inclusive % // lvi.iSubItem = 2; lvi.mask = LVIF_TEXT; StringCchPrintf(Buffer, MAX_PATH, L"%.2f", (PcEntry->Inclusive * 100.0) / (Exclusive * 1.0)); lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); // // Exclusive // lvi.iSubItem = 3; lvi.mask = LVIF_TEXT; StringCchPrintf(Buffer, MAX_PATH, L"%u", PcEntry->Exclusive); lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); // // Exclusive % // lvi.iSubItem = 4; lvi.mask = LVIF_TEXT; StringCchPrintf(Buffer, MAX_PATH, L"%.2f", (PcEntry->Exclusive * 100.0) / (Exclusive * 1.0)); lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); // // Dll // lvi.iSubItem = 5; lvi.mask = LVIF_TEXT; ApsGetDllBaseNameById(Head, PcEntry->DllId, Buffer, MAX_PATH); lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); // // Line // if (PcEntry->LineId != -1) { ASSERT(Line != NULL); LineEntry = Line + PcEntry->LineId; StringCchPrintf(Buffer, MAX_PATH, L"%S:%u", LineEntry->File, LineEntry->Line); lvi.iSubItem = 6; lvi.mask = LVIF_TEXT; lvi.pszText = Buffer; ListView_SetItem(hWndCtrl, &lvi); } else { lvi.iSubItem = 6; lvi.mask = LVIF_TEXT; lvi.pszText = L""; ListView_SetItem(hWndCtrl, &lvi); } // // Move to next PC // Number += 1; ListEntry = ListEntry->Flink; } } ApsDestroySymbolTable(TextTable); } return 0L; }