summaryrefslogtreecommitdiffstats
path: root/WebKitTools/record-memory-win
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:52 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:52 -0800
commit8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2 (patch)
tree11425ea0b299d6fb89c6d3618a22d97d5bf68d0f /WebKitTools/record-memory-win
parent648161bb0edfc3d43db63caed5cc5213bc6cb78f (diff)
downloadexternal_webkit-8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2.zip
external_webkit-8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2.tar.gz
external_webkit-8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'WebKitTools/record-memory-win')
-rw-r--r--WebKitTools/record-memory-win/main.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/WebKitTools/record-memory-win/main.cpp b/WebKitTools/record-memory-win/main.cpp
new file mode 100644
index 0000000..e660afe
--- /dev/null
+++ b/WebKitTools/record-memory-win/main.cpp
@@ -0,0 +1,187 @@
+#include <windows.h>
+#include <assert.h>
+#include <psapi.h>
+#include <stdio.h>
+#include <tchar.h>
+#include <time.h>
+#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;
+
+HRESULT ProcessArgs(int argc, TCHAR *argv[]);
+HRESULT PrintUsage();
+void UseImage(void (functionForQueryType(HANDLE)));
+void QueryContinuously(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[])
+{
+ HRESULT result = ProcessArgs(argc, argv);
+ if (FAILED(result))
+ return result;
+
+ UseImage(QueryContinuously);
+ return S_OK;
+}
+
+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")))
+ 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")) ||
+ wcsstr(argument, _T("--interval"))) {
+ gQueryInterval = _wtoi(argv[++count]);
+ if (gQueryInterval < 1) {
+ printf("ERROR: invalid interval\n");
+ return E_INVALIDARG;
+ }
+ } else if (wcsstr(argument, _T("-d")) ||
+ wcsstr(argument, _T("--duration"))) {
+ gDuration = _wtoi(argv[++count]);
+ if (gDuration < 1) {
+ printf("ERROR: invalid duration\n");
+ return E_INVALIDARG;
+ }
+ } else {
+ _tprintf(_T("ERROR: unrecognized argument \"%s\"\n"), (LPCTSTR)argument);
+ return PrintUsage();
+ }
+ }
+ if (argc < 2 || !wcslen(gCommandLine) ) {
+ printf("ERROR: executable path is required\n");
+ return PrintUsage();
+ }
+ return S_OK;
+}
+
+HRESULT PrintUsage()
+{
+ printf("record-memory-win --exe EXE_PATH\n");
+ printf(" Launch an executable and print the memory usage (in Private Bytes)\n");
+ printf(" of the process.\n\n");
+ printf("Usage:\n");
+ printf("-h [--help] : Print usage\n");
+ printf("--exe arg : Launch specified image. Required\n");
+ 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");
+ return E_FAIL;
+}
+
+void UseImage(void (functionForQueryType(HANDLE)))
+{
+ STARTUPINFO si = {0};
+ si.cb = sizeof(STARTUPINFO);
+ PROCESS_INFORMATION pi = {0};
+
+ // Start the child process.
+ if(!CreateProcess( NULL, // No module name (use command line)
+ gCommandLine, // Command line
+ NULL, // Process handle not inheritable
+ NULL, // Thread handle not inheritable
+ FALSE, // Set handle inheritance to FALSE
+ 0, // No creation flags
+ NULL, // Use parent's environment block
+ NULL, // Use parent's starting directory
+ &si, // Pointer to STARTUPINFO structure
+ &pi )) // Pointer to PROCESS_INFORMATION structure
+ printf("CreateProcess failed (%d)\n", GetLastError());
+ else {
+ printf("Created process\n");
+ functionForQueryType(pi.hProcess);
+ // Close process and thread handles.
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
+ }
+}
+
+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);
+ while(memUsage && !pastDuration) {
+ printf( "%u\n", memUsage );
+ Sleep(gQueryInterval*1000);
+ memUsage = gSingleProcess ? OneQuery(hProcess) : OneQueryMP(hProcess);
+ pastDuration = gDuration > 0 ? ElapsedTime(startTime) > gDuration : false;
+ }
+}
+
+// returns elapsed time in seconds
+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;
+}