X-Git-Url: https://git.webkit.org/?p=WebKit-https.git;a=blobdiff_plain;f=Tools%2Frecord-memory-win%2Fmain.cpp;h=934f10102e57b5d07b8f8822b4427950bd482b95;hp=e660afeb2dec147f02b43842d7a6ca6fa7b8366e;hb=d11a9df775c3322b071ae61990649fad1417772f;hpb=f0edadc99760abd3d3b90ab365ea643011330ebd diff --git a/Tools/record-memory-win/main.cpp b/Tools/record-memory-win/main.cpp index e660afeb2dec..934f10102e57 100644 --- a/Tools/record-memory-win/main.cpp +++ b/Tools/record-memory-win/main.cpp @@ -4,12 +4,12 @@ #include #include #include +#include #include "Shlwapi.h" #pragma comment(lib, "psapi.lib") #pragma comment(lib, "shlwapi.lib") -bool gSingleProcess = true; int gQueryInterval = 5; // seconds time_t gDuration = 0; // seconds LPTSTR gCommandLine; @@ -18,9 +18,8 @@ HRESULT ProcessArgs(int argc, TCHAR *argv[]); HRESULT PrintUsage(); void UseImage(void (functionForQueryType(HANDLE))); void QueryContinuously(HANDLE hProcess); +int EvalProcesses(HANDLE hProcess); time_t ElapsedTime(time_t startTime); -unsigned int OneQuery(HANDLE hProcess); -unsigned int OneQueryMP(HANDLE hProcess); int __cdecl _tmain (int argc, TCHAR *argv[]) { @@ -37,14 +36,11 @@ HRESULT ProcessArgs(int argc, TCHAR *argv[]) LPTSTR argument; for( int count = 1; count < argc; count++ ) { argument = argv[count] ; - if (wcsstr(argument, _T("-h")) || - wcsstr(argument, _T("--help"))) + if (wcsstr(argument, _T("-h")) || wcsstr(argument, _T("--help"))) return PrintUsage(); else if (wcsstr(argument, _T("--exe"))) { gCommandLine = argv[++count]; - if (wcsstr(gCommandLine, _T("chrome.exe"))) - gSingleProcess = false; - } else if (wcsstr(argument, _T("-i")) || + } else if (wcsstr(argument, _T("-i")) || wcsstr(argument, _T("--interval"))) { gQueryInterval = _wtoi(argv[++count]); if (gQueryInterval < 1) { @@ -81,11 +77,93 @@ HRESULT PrintUsage() printf("-i [--interval] arg : Print memory usage every arg seconds. Default: 5 seconds\n"); printf("-d [--duration] arg : Run for up to arg seconds. Default: no limit\n\n"); printf("Examples:\n"); - printf(" record-memory-win --exe \"C:\\Program Files\\Safari\\Safari.exe\"\n"); - printf(" record-memory-win --exe Safari.exe -i 10 -d 7200\n"); + printf(" record-memory-win --exe \"C:\\Program Files\\Safari\\Safari.exe /newprocess\"\n"); + printf(" record-memory-win --exe \"Safari.exe /newprocess\" -i 10 -d 7200\n"); + printf(" NOTE: Close all other browser intances to ensure launching in a new process\n"); + printf(" Or, pass the /newprocess (or equivalent) argument to the browser\n"); return E_FAIL; } +unsigned int getMemoryInfo(DWORD processID) +{ + unsigned int memInfo = 0; + HANDLE hProcess; + PROCESS_MEMORY_COUNTERS_EX pmc; + + hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | + PROCESS_VM_READ, + FALSE, processID ); + if (NULL == hProcess) + return 0; + + if (GetProcessMemoryInfo( hProcess, (PPROCESS_MEMORY_COUNTERS)&pmc, sizeof(pmc))) { + memInfo = (pmc.PrivateUsage); + } + + CloseHandle( hProcess ); + return memInfo; +} + +void printProcessInfo(DWORD processID) +{ + TCHAR szProcessName[MAX_PATH] = TEXT(""); + + // Get a handle to the process. + HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | + PROCESS_VM_READ, + FALSE, processID ); + + // Get the process name. + if (NULL != hProcess) { + HMODULE hMod; // An array that receives the list of module handles. + DWORD cbNeeded; //The number of bytes required to store all module handles in the Module array + + if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) { + GetModuleBaseName(hProcess, hMod, szProcessName, + sizeof(szProcessName)/sizeof(TCHAR)); + } + } + + // Print the process name and identifier of matching strings, ignoring case + _tprintf(TEXT("%s (PID: %u)\n"), szProcessName, processID); + + // Release the handle to the process. + CloseHandle( hProcess ); +} + +int evalProcesses(HANDLE hProcess) +{ + if (NULL == hProcess) + return 0; + + unsigned int totalMemUsage = 0; + DWORD processID = GetProcessId(hProcess); + + HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + PROCESSENTRY32 processEntry = { 0 }; + processEntry.dwSize = sizeof(PROCESSENTRY32); + + // Retrieves information about the first process encountered in a system snapshot + if(Process32First(hProcessSnapshot, &processEntry)) { + do { + // if th32processID = processID, we are the parent process! + // if th32ParentProcessID = processID, we are a child process! + if ((processEntry.th32ProcessID == processID) || (processEntry.th32ParentProcessID == processID)) { + unsigned int procMemUsage = 0; + // Record parent process memory + procMemUsage = getMemoryInfo(processEntry.th32ProcessID); + totalMemUsage += procMemUsage; + } + // Retrieves information about the next process recorded in a system snapshot. + } while(Process32Next(hProcessSnapshot, &processEntry)); + } + + CloseHandle(hProcessSnapshot); + return totalMemUsage; +} + + void UseImage(void (functionForQueryType(HANDLE))) { STARTUPINFO si = {0}; @@ -105,7 +183,7 @@ void UseImage(void (functionForQueryType(HANDLE))) &pi )) // Pointer to PROCESS_INFORMATION structure printf("CreateProcess failed (%d)\n", GetLastError()); else { - printf("Created process\n"); + printf("Created process with id: %d\n", pi.dwProcessId); functionForQueryType(pi.hProcess); // Close process and thread handles. CloseHandle( pi.hProcess ); @@ -118,11 +196,11 @@ void QueryContinuously(HANDLE hProcess) Sleep(2000); // give the process some time to launch bool pastDuration = false; time_t startTime = time(NULL); - unsigned int memUsage = gSingleProcess ? OneQuery(hProcess) : OneQueryMP(hProcess); + unsigned int memUsage = evalProcesses(hProcess); while(memUsage && !pastDuration) { printf( "%u\n", memUsage ); Sleep(gQueryInterval*1000); - memUsage = gSingleProcess ? OneQuery(hProcess) : OneQueryMP(hProcess); + memUsage = evalProcesses(hProcess); pastDuration = gDuration > 0 ? ElapsedTime(startTime) > gDuration : false; } } @@ -133,55 +211,3 @@ time_t ElapsedTime(time_t startTime) time_t currentTime = time(NULL); return currentTime - startTime; } - -// returns Commit Size (Private Bytes) in bytes -unsigned int OneQuery(HANDLE hProcess) -{ - PROCESS_MEMORY_COUNTERS_EX pmc; - if (NULL == hProcess) - return 0; - if (GetProcessMemoryInfo(hProcess, (PPROCESS_MEMORY_COUNTERS)&pmc, sizeof(pmc))) - return (unsigned)pmc.PrivateUsage; - return 0; -} - -// returns Commit Size (Private Bytes) in bytes for multi-process executables -unsigned int OneQueryMP(HANDLE hProcess) -{ - unsigned int memUsage = 0; - TCHAR monitoredProcessName[MAX_PATH]; - GetProcessImageFileName(hProcess, monitoredProcessName, sizeof(monitoredProcessName)/sizeof(TCHAR)); - LPTSTR shortProcessName = PathFindFileName(monitoredProcessName); - DWORD aProcesses[1024], cbNeeded, cProcesses; - HANDLE hFoundProcess; - if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) - return 0; - - // Calculate how many process identifiers were returned. - cProcesses = cbNeeded / sizeof(DWORD); - // find existing process - for (unsigned int i = 0; i < cProcesses; i++) - if (aProcesses[i] != 0) { - DWORD retVal = 0; - TCHAR foundProcessName[MAX_PATH]; - - // Get a handle to the process. - hFoundProcess = OpenProcess(PROCESS_QUERY_INFORMATION | - PROCESS_VM_READ, - FALSE, aProcesses[i]); - - // Get the process name. - if (NULL != hFoundProcess) { - HMODULE hMod; - DWORD cbNeeded; - - if (EnumProcessModules(hFoundProcess, &hMod, sizeof(hMod), &cbNeeded)) { - GetModuleBaseName(hFoundProcess, hMod, foundProcessName, sizeof(foundProcessName)/sizeof(TCHAR)); - if (wcsstr(foundProcessName, shortProcessName)) - memUsage += OneQuery(hFoundProcess); - } - } - CloseHandle(hFoundProcess); - } - return memUsage; -}