From a06bdb456f89b7ae33c4f755cfea19623ee530e8 Mon Sep 17 00:00:00 2001 From: CHEN FENG <chen3feng@gmail.com> Date: Tue, 15 Aug 2023 19:07:44 +0800 Subject: [PATCH 1/3] Fix build error on VS 2022 --- sleepy.vcxproj | 4 ++++ src/copyfiles.bat | 2 +- src/crashback/badapp/badapp.vcxproj | 4 ++++ src/crashback/client/crashback.vcxproj | 4 ++++ src/crashback/crashreport/crashreport.vcxproj | 4 ++++ src/profiler/processinfo.cpp | 2 +- src/profiler/profiler.cpp | 6 +++--- src/utils/except.h | 15 +++++++++++---- thirdparty/ms/dbghelp.h | 4 ++-- thirdparty/wine | 2 +- thirdparty/wxWidgetsSetup/wxWidgetsSetup.vcxproj | 3 +++ 11 files changed, 38 insertions(+), 12 deletions(-) diff --git a/sleepy.vcxproj b/sleepy.vcxproj index 86466d5d..813582ab 100644 --- a/sleepy.vcxproj +++ b/sleepy.vcxproj @@ -28,18 +28,22 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/copyfiles.bat b/src/copyfiles.bat index 9c46ef42..e7f10207 100644 --- a/src/copyfiles.bat +++ b/src/copyfiles.bat @@ -18,7 +18,7 @@ if errorlevel 1 ((@echo Failed to copy dbghelp_*) & (exit /b 1)) if not exist "%DBGHELPERS%\dbghelpw.dll" copy /y "thirdparty\wine\dlls\dbghelp\vs\bin\%PLATFORM%\%CONFIGURATION%\dbghelpw.dll" "%DEST%" if errorlevel 1 ((@echo Failed to copy dbghelpw.dll) & (exit /b 1)) -if %PLATFORM%==x64 if not exist "%DBGHELPERS%\dbghelpw_wow64.dll" copy /y "thirdparty\wine\dlls\dbghelp\vs\bin\%PLATFORM%\%CONFIGURATION% - Wow64\dbghelpw.dll" "%DEST%\dbghelpw_wow64.dll" +if %PLATFORM%==x64 if not exist "%DBGHELPERS%\dbghelpw_wow64.dll" copy /y "thirdparty\wine\dlls\dbghelp\vs\bin\%PLATFORM%\%CONFIGURATION%\dbghelpw.dll" "%DEST%\dbghelpw_wow64.dll" if errorlevel 1 ((@echo Failed to copy dbghelpw_wow64.dll) & (exit /b 1)) if %PLATFORM%==Win32 set PLATFORM_BITS=32 diff --git a/src/crashback/badapp/badapp.vcxproj b/src/crashback/badapp/badapp.vcxproj index af8035a2..f9c732d4 100644 --- a/src/crashback/badapp/badapp.vcxproj +++ b/src/crashback/badapp/badapp.vcxproj @@ -28,19 +28,23 @@ <ConfigurationType>Application</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/crashback/client/crashback.vcxproj b/src/crashback/client/crashback.vcxproj index 3f85de15..cf8e85f0 100644 --- a/src/crashback/client/crashback.vcxproj +++ b/src/crashback/client/crashback.vcxproj @@ -29,19 +29,23 @@ <ConfigurationType>StaticLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>false</WholeProgramOptimization> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>false</WholeProgramOptimization> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/crashback/crashreport/crashreport.vcxproj b/src/crashback/crashreport/crashreport.vcxproj index 0eb72443..20d696a5 100644 --- a/src/crashback/crashreport/crashreport.vcxproj +++ b/src/crashback/crashreport/crashreport.vcxproj @@ -28,19 +28,23 @@ <ConfigurationType>Application</ConfigurationType> <CharacterSet>NotSet</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>NotSet</CharacterSet> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>NotSet</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <CharacterSet>NotSet</CharacterSet> + <PlatformToolset>v143</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/profiler/processinfo.cpp b/src/profiler/processinfo.cpp index 21df8abc..7864d8ba 100644 --- a/src/profiler/processinfo.cpp +++ b/src/profiler/processinfo.cpp @@ -133,4 +133,4 @@ ProcessInfo ProcessInfo::FindProcessById(DWORD process_id) return process; } throw SleepyException("Could not found process with specified id: " + std::to_string((unsigned long long) process_id)); -} \ No newline at end of file +} diff --git a/src/profiler/profiler.cpp b/src/profiler/profiler.cpp index 13fe2883..e07d9f4e 100644 --- a/src/profiler/profiler.cpp +++ b/src/profiler/profiler.cpp @@ -112,7 +112,7 @@ void applyHacks(HANDLE process_handle, CONTEXT32 &context) // First, skip over any stub functions (a useless push/mov/pop header, followed by a jump). // Move instead to the jump target. - if (ReadProcessMemory(process_handle, (LPCVOID)context.Eip, tmp, 16, &numRead) && numRead >= 16) + if (ReadProcessMemory(process_handle, (LPCVOID)(DWORD64)context.Eip, tmp, 16, &numRead) && numRead >= 16) { int n = 0; @@ -136,13 +136,13 @@ void applyHacks(HANDLE process_handle, CONTEXT32 &context) } // Skip over any jmp [__imp__blah] thunks. - if (ReadProcessMemory(process_handle, (LPCVOID)context.Eip, tmp, 16, &numRead) && numRead >= 16) + if (ReadProcessMemory(process_handle, (LPCVOID)(DWORD64)context.Eip, tmp, 16, &numRead) && numRead >= 16) { // Look for "jmp [foo]", and move the IP forward to '[foo]'. if (tmp[0] == 0xff && tmp[1] == 0x25) { DWORD ptr = (tmp[5] << 24) | (tmp[4] << 16) | (tmp[3] << 8) | (tmp[2] << 0); - if (ReadProcessMemory(process_handle, (LPCVOID)ptr, tmp, 4, &numRead) && numRead >= 4) + if (ReadProcessMemory(process_handle, (LPCVOID)(DWORD64)ptr, tmp, 4, &numRead) && numRead >= 4) { context.Eip = (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | (tmp[0] << 0); } diff --git a/src/utils/except.h b/src/utils/except.h index da5376ce..735aeb2d 100644 --- a/src/utils/except.h +++ b/src/utils/except.h @@ -23,6 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #pragma once +#include <codecvt> +#include <locale> #include <stdexcept> #include <string> @@ -30,15 +32,20 @@ class SleepyException : public std::runtime_error { std::wstring _what; - std::string helper(const wchar_t *what) + std::string helper(const std::wstring& what) { // Need a temporary to build std::string. // Can't use _what in initialization-list because // it will always be initialized after the superclass. // Can't use _what here because it is still not initialized // and contains junk. - std::wstring ws(what); - return std::string(ws.begin(), ws.end()); + + // setup converter + using convert_type = std::codecvt_utf8<wchar_t>; + std::wstring_convert<convert_type, wchar_t> converter; + + // use converter (.to_bytes: wstr->str, .from_bytes: str->wstr) + return converter.to_bytes(what);; } public: @@ -46,7 +53,7 @@ class SleepyException : public std::runtime_error : std::runtime_error(what), _what(std::wstring(what.begin(), what.end())) {} SleepyException(const std::wstring &what) - : std::runtime_error(std::string(what.begin(), what.end())), _what(what) {} + : std::runtime_error(helper(what)), _what(what) {} SleepyException(const wchar_t *what) : std::runtime_error(helper(what)), _what(what) {} diff --git a/thirdparty/ms/dbghelp.h b/thirdparty/ms/dbghelp.h index f6f67f0c..afe918dc 100644 --- a/thirdparty/ms/dbghelp.h +++ b/thirdparty/ms/dbghelp.h @@ -1540,7 +1540,7 @@ SymGetHomeDirectoryW( __in size_t size ); -typedef enum { +enum { hdBase = 0, // root directory for dbghelp hdSym, // where symbols are stored hdSrc, // where source is stored @@ -3056,7 +3056,7 @@ SymSrvStoreFileW( // used by SymGetSymbolFile's "Type" parameter -typedef enum { +enum { sfImage = 0, sfDbg, sfPdb, diff --git a/thirdparty/wine b/thirdparty/wine index 12126ff2..d47751be 160000 --- a/thirdparty/wine +++ b/thirdparty/wine @@ -1 +1 @@ -Subproject commit 12126ff2bc695847c67bf36f133472f806501365 +Subproject commit d47751be64569a3d577f772ae7b8f5ebcec4aeab diff --git a/thirdparty/wxWidgetsSetup/wxWidgetsSetup.vcxproj b/thirdparty/wxWidgetsSetup/wxWidgetsSetup.vcxproj index 5cd535c7..d6ebe35e 100644 --- a/thirdparty/wxWidgetsSetup/wxWidgetsSetup.vcxproj +++ b/thirdparty/wxWidgetsSetup/wxWidgetsSetup.vcxproj @@ -11,6 +11,9 @@ <RootNamespace>wxWidgetsSetup</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ItemGroup> <CustomBuild Include="setup.h"> From 17ef6c748db2db07ab1db689f1b294c012a4a5b4 Mon Sep 17 00:00:00 2001 From: CHEN FENG <chen3feng@gmail.com> Date: Tue, 15 Aug 2023 19:16:20 +0800 Subject: [PATCH 2/3] Add 'Command Line' column in process selection ListView --- src/profiler/processinfo.cpp | 42 +++++++++++++++++++++++++++++++ src/profiler/processinfo.h | 2 ++ src/wxProfilerGUI/processlist.cpp | 26 +++++++++++++++++++ src/wxProfilerGUI/processlist.h | 2 ++ 4 files changed, 72 insertions(+) diff --git a/src/profiler/processinfo.cpp b/src/profiler/processinfo.cpp index 7864d8ba..fbce55bf 100644 --- a/src/profiler/processinfo.cpp +++ b/src/profiler/processinfo.cpp @@ -27,8 +27,49 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "../utils/osutils.h" #include "../utils/except.h" #include <windows.h> +#include <winternl.h> #include <tlhelp32.h> +#ifndef STATUS_SUCCESS +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +#endif + +static std::wstring GetProcessCommandLine(HANDLE processHandle) +{ + std::wstring commandLine; + do { + // NtQueryInformationProcess is an internal function, So, we need to get the address of the function from ntdll + auto pNtQueryInformationProcess = reinterpret_cast<decltype(&::NtQueryInformationProcess)>( + GetProcAddress(GetModuleHandle(L"ntdll"), "NtQueryInformationProcess")); + if (!pNtQueryInformationProcess) break; + + PROCESS_BASIC_INFORMATION pbi; + if (pNtQueryInformationProcess(processHandle, ProcessBasicInformation, &pbi, sizeof(pbi), nullptr) != STATUS_SUCCESS) + { + break; + } + + // Reading the PEB structure of the process + PEB peb; + if (!ReadProcessMemory(processHandle, pbi.PebBaseAddress, &peb, sizeof(peb), nullptr)) + { + break; + } + + // Reading the process parameters structure + RTL_USER_PROCESS_PARAMETERS upp; + if (!ReadProcessMemory(processHandle, peb.ProcessParameters, &upp, sizeof(upp), nullptr)) + { + break; + } + + commandLine.resize(upp.CommandLine.Length); + ReadProcessMemory(processHandle, upp.CommandLine.Buffer, &commandLine[0], upp.CommandLine.Length, nullptr); + } while (0); + + return commandLine; +} + ProcessInfo::ProcessInfo(DWORD id_, const std::wstring& name_, HANDLE process_handle_) : id(id_), name(name_), @@ -40,6 +81,7 @@ ProcessInfo::ProcessInfo(DWORD id_, const std::wstring& name_, HANDLE process_ha #ifdef _WIN64 is64Bits = Is64BitProcess(process_handle); #endif + commandLine = GetProcessCommandLine(process_handle); } ProcessInfo::~ProcessInfo() diff --git a/src/profiler/processinfo.h b/src/profiler/processinfo.h index 398f7624..45f1bc66 100644 --- a/src/profiler/processinfo.h +++ b/src/profiler/processinfo.h @@ -58,6 +58,7 @@ class ProcessInfo #ifdef _WIN64 bool getIs64Bits() const { return is64Bits; } #endif + const std::wstring& getCommandLine() const { return commandLine; } FILETIME prevKernelTime, prevUserTime; int cpuUsage; __int64 totalCpuTimeMs; @@ -69,6 +70,7 @@ class ProcessInfo #ifdef _WIN64 bool is64Bits; #endif + std::wstring commandLine; }; diff --git a/src/wxProfilerGUI/processlist.cpp b/src/wxProfilerGUI/processlist.cpp index 95d68c4c..94d20172 100644 --- a/src/wxProfilerGUI/processlist.cpp +++ b/src/wxProfilerGUI/processlist.cpp @@ -63,6 +63,8 @@ ProcessList::ProcessList(wxWindow *parent, const wxPoint& pos, InsertColumn(COL_TOTALCPU, itemCol); itemCol.m_text = _T("PID"); InsertColumn(COL_PID, itemCol); + itemCol.m_text = _T("Command Line"); + InsertColumn(COL_COMMANDLINE, itemCol); SetColumnWidth(COL_NAME, FromDIP(270)); #ifdef _WIN64 @@ -71,6 +73,7 @@ ProcessList::ProcessList(wxWindow *parent, const wxPoint& pos, SetColumnWidth(COL_CPUUSAGE, FromDIP(50)); SetColumnWidth(COL_TOTALCPU, FromDIP(70)); SetColumnWidth(COL_PID, FromDIP(50)); + SetColumnWidth(COL_COMMANDLINE, FromDIP(500)); sort_column = COL_CPUUSAGE; sort_dir = SORT_DOWN; @@ -232,6 +235,18 @@ struct TypeDescPred { bool operator () (const ProcessInfo &a, const ProcessInfo } }; #endif +struct CommandLineAscPred { + bool operator () (const ProcessInfo& a, const ProcessInfo& b) { + return wcsicmp(a.getCommandLine().c_str(), b.getCommandLine().c_str()) < 0; + } +}; + +struct CommandLineDescPred { + bool operator () (const ProcessInfo& a, const ProcessInfo& b) { + return wcsicmp(a.getCommandLine().c_str(), b.getCommandLine().c_str()) > 0; + } +}; + void ProcessList::sortByName() { if (sort_dir == SORT_UP) @@ -273,6 +288,15 @@ void ProcessList::sortByType() std::stable_sort(processes.begin(), processes.end(), TypeDescPred()); } #endif + +void ProcessList::sortByCommandLine() +{ + if (sort_dir == SORT_UP) + std::stable_sort(processes.begin(), processes.end(), CommandLineAscPred()); + else + std::stable_sort(processes.begin(), processes.end(), CommandLineDescPred()); +} + void ProcessList::OnSort(wxListEvent& event) { SetSortImage(sort_column, SORT_NONE); @@ -301,6 +325,7 @@ void ProcessList::updateSorting() #ifdef _WIN64 case COL_TYPE: sortByType(); break; #endif + case COL_COMMANDLINE: sortByCommandLine(); break; } fillList(); } @@ -334,6 +359,7 @@ void ProcessList::fillList() SetItem(i,COL_TYPE,"32-bit"); } #endif + this->SetItem(i, COL_COMMANDLINE, processes[i].getCommandLine()); } Thaw(); } diff --git a/src/wxProfilerGUI/processlist.h b/src/wxProfilerGUI/processlist.h index 7a7a3647..901f8bc2 100644 --- a/src/wxProfilerGUI/processlist.h +++ b/src/wxProfilerGUI/processlist.h @@ -67,6 +67,7 @@ class ProcessList : public wxSortedListCtrl #ifdef _WIN64 void sortByType(); #endif + void sortByCommandLine(); void reloadSymbols(bool download); const ProcessInfo* getSelectedProcess(); @@ -82,6 +83,7 @@ class ProcessList : public wxSortedListCtrl COL_CPUUSAGE, COL_TOTALCPU, COL_PID, + COL_COMMANDLINE, NUM_COLUMNS }; From f5caa5039b80da831ff2b251c9b358416788a0b7 Mon Sep 17 00:00:00 2001 From: CHEN FENG <chen3feng@gmail.com> Date: Mon, 16 Oct 2023 09:26:13 +0800 Subject: [PATCH 3/3] Show window title in the process selection list --- src/profiler/processinfo.cpp | 35 +++++++++++++++++++++++++++++++ src/profiler/processinfo.h | 2 ++ src/profiler/symbolinfo.cpp | 2 +- src/wxProfilerGUI/processlist.cpp | 25 ++++++++++++++++++++++ src/wxProfilerGUI/processlist.h | 2 ++ 5 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/profiler/processinfo.cpp b/src/profiler/processinfo.cpp index fbce55bf..cff61448 100644 --- a/src/profiler/processinfo.cpp +++ b/src/profiler/processinfo.cpp @@ -70,6 +70,40 @@ static std::wstring GetProcessCommandLine(HANDLE processHandle) return commandLine; } +static bool IsMainWindow(HWND hWnd) +{ + return GetWindow(hWnd, GW_OWNER) == nullptr && IsWindowVisible(hWnd); +} + +struct EnumWindowInfo +{ + DWORD pid; + HWND hWndFound; +}; + +static BOOL CALLBACK EnumWindowsCallback(HWND hWnd, LPARAM lParam) +{ + EnumWindowInfo* info = reinterpret_cast<EnumWindowInfo*>(lParam); + DWORD pid = 0; + GetWindowThreadProcessId(hWnd, &pid); + + if (pid != info->pid) return TRUE; + if (!IsMainWindow(hWnd)) return TRUE; + info->hWndFound = hWnd; + return FALSE; +} + +std::wstring GetProcessMainWindowTitle(DWORD pid) +{ + EnumWindowInfo info = {pid, nullptr}; + EnumWindows(EnumWindowsCallback, reinterpret_cast<LPARAM>(&info)); + if (info.hWndFound == nullptr) return {}; + std::wstring title(256, '\0'); + int len = GetWindowTextW(info.hWndFound, &title[0], static_cast<int>(title.size())); + title.resize(len); + return title; +} + ProcessInfo::ProcessInfo(DWORD id_, const std::wstring& name_, HANDLE process_handle_) : id(id_), name(name_), @@ -81,6 +115,7 @@ ProcessInfo::ProcessInfo(DWORD id_, const std::wstring& name_, HANDLE process_ha #ifdef _WIN64 is64Bits = Is64BitProcess(process_handle); #endif + title = GetProcessMainWindowTitle(id); commandLine = GetProcessCommandLine(process_handle); } diff --git a/src/profiler/processinfo.h b/src/profiler/processinfo.h index 45f1bc66..30c87cc6 100644 --- a/src/profiler/processinfo.h +++ b/src/profiler/processinfo.h @@ -58,6 +58,7 @@ class ProcessInfo #ifdef _WIN64 bool getIs64Bits() const { return is64Bits; } #endif + const std::wstring& getTitle() const { return title; } const std::wstring& getCommandLine() const { return commandLine; } FILETIME prevKernelTime, prevUserTime; int cpuUsage; @@ -70,6 +71,7 @@ class ProcessInfo #ifdef _WIN64 bool is64Bits; #endif + std::wstring title; std::wstring commandLine; }; diff --git a/src/profiler/symbolinfo.cpp b/src/profiler/symbolinfo.cpp index ff34effb..8c4dae29 100644 --- a/src/profiler/symbolinfo.cpp +++ b/src/profiler/symbolinfo.cpp @@ -157,7 +157,7 @@ void SymbolInfo::loadSymbolsUsing(DbgHelp* dbgHelp, const std::wstring& sympath) { // This is a secondary dbgHelp, so just complement debug // information for modules that have none. - + for (size_t m=0;m<modules.size();m++) { Module &mod = modules[m]; diff --git a/src/wxProfilerGUI/processlist.cpp b/src/wxProfilerGUI/processlist.cpp index 94d20172..0dd35e52 100644 --- a/src/wxProfilerGUI/processlist.cpp +++ b/src/wxProfilerGUI/processlist.cpp @@ -63,6 +63,8 @@ ProcessList::ProcessList(wxWindow *parent, const wxPoint& pos, InsertColumn(COL_TOTALCPU, itemCol); itemCol.m_text = _T("PID"); InsertColumn(COL_PID, itemCol); + itemCol.m_text = _T("Title"); + InsertColumn(COL_TITLE, itemCol); itemCol.m_text = _T("Command Line"); InsertColumn(COL_COMMANDLINE, itemCol); @@ -73,6 +75,7 @@ ProcessList::ProcessList(wxWindow *parent, const wxPoint& pos, SetColumnWidth(COL_CPUUSAGE, FromDIP(50)); SetColumnWidth(COL_TOTALCPU, FromDIP(70)); SetColumnWidth(COL_PID, FromDIP(50)); + SetColumnWidth(COL_TITLE, FromDIP(200)); SetColumnWidth(COL_COMMANDLINE, FromDIP(500)); sort_column = COL_CPUUSAGE; @@ -235,6 +238,18 @@ struct TypeDescPred { bool operator () (const ProcessInfo &a, const ProcessInfo } }; #endif +struct TitleAscPred { + bool operator () (const ProcessInfo& a, const ProcessInfo& b) { + return wcsicmp(a.getTitle().c_str(), b.getTitle().c_str()) < 0; + } +}; + +struct TitleDescPred { + bool operator () (const ProcessInfo& a, const ProcessInfo& b) { + return wcsicmp(a.getTitle().c_str(), b.getTitle().c_str()) > 0; + } +}; + struct CommandLineAscPred { bool operator () (const ProcessInfo& a, const ProcessInfo& b) { return wcsicmp(a.getCommandLine().c_str(), b.getCommandLine().c_str()) < 0; @@ -289,6 +304,14 @@ void ProcessList::sortByType() } #endif +void ProcessList::sortByTitle() +{ + if (sort_dir == SORT_UP) + std::stable_sort(processes.begin(), processes.end(), TitleAscPred()); + else + std::stable_sort(processes.begin(), processes.end(), TitleDescPred()); +} + void ProcessList::sortByCommandLine() { if (sort_dir == SORT_UP) @@ -325,6 +348,7 @@ void ProcessList::updateSorting() #ifdef _WIN64 case COL_TYPE: sortByType(); break; #endif + case COL_TITLE: sortByTitle(); break; case COL_COMMANDLINE: sortByCommandLine(); break; } fillList(); @@ -359,6 +383,7 @@ void ProcessList::fillList() SetItem(i,COL_TYPE,"32-bit"); } #endif + this->SetItem(i, COL_TITLE, processes[i].getTitle()); this->SetItem(i, COL_COMMANDLINE, processes[i].getCommandLine()); } Thaw(); diff --git a/src/wxProfilerGUI/processlist.h b/src/wxProfilerGUI/processlist.h index 901f8bc2..a450040b 100644 --- a/src/wxProfilerGUI/processlist.h +++ b/src/wxProfilerGUI/processlist.h @@ -67,6 +67,7 @@ class ProcessList : public wxSortedListCtrl #ifdef _WIN64 void sortByType(); #endif + void sortByTitle(); void sortByCommandLine(); void reloadSymbols(bool download); @@ -83,6 +84,7 @@ class ProcessList : public wxSortedListCtrl COL_CPUUSAGE, COL_TOTALCPU, COL_PID, + COL_TITLE, COL_COMMANDLINE, NUM_COLUMNS };