summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormbelshe@google.com <mbelshe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-29 15:53:26 +0000
committermbelshe@google.com <mbelshe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-29 15:53:26 +0000
commite288a8e7c2b0b1faf93d925128c84620a044bdba (patch)
tree89495ea3ff186ddf0e0d0763ce6467526756d124
parent0dbf657461ad991e09707c4ee7e1f9f3000903e4 (diff)
downloadchromium_src-e288a8e7c2b0b1faf93d925128c84620a044bdba.zip
chromium_src-e288a8e7c2b0b1faf93d925128c84620a044bdba.tar.gz
chromium_src-e288a8e7c2b0b1faf93d925128c84620a044bdba.tar.bz2
Support for showing memory usage of 64-bit IE in a 32-bit Chromium
This is a changelist for http://codereview.chromium.org/75031 by Kent Tamura (tkent@google.com) Review URL: http://codereview.chromium.org/100111 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14846 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/process_util_win.cc37
-rw-r--r--chrome/browser/memory_details.cc70
-rw-r--r--chrome/browser/memory_details.h1
-rw-r--r--chrome/browser/resources/about_memory.html3
4 files changed, 66 insertions, 45 deletions
diff --git a/base/process_util_win.cc b/base/process_util_win.cc
index fc05664..45a23e8 100644
--- a/base/process_util_win.cc
+++ b/base/process_util_win.cc
@@ -524,21 +524,30 @@ void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const {
size_t committed_mapped = 0;
size_t committed_image = 0;
void* base_address = NULL;
- while (VirtualQueryEx(process_, base_address, &mbi,
- sizeof(MEMORY_BASIC_INFORMATION)) ==
- sizeof(MEMORY_BASIC_INFORMATION)) {
- if (mbi.State == MEM_COMMIT) {
- if (mbi.Type == MEM_PRIVATE) {
- committed_private += mbi.RegionSize;
- } else if (mbi.Type == MEM_MAPPED) {
- committed_mapped += mbi.RegionSize;
- } else if (mbi.Type == MEM_IMAGE) {
- committed_image += mbi.RegionSize;
- } else {
- NOTREACHED();
- }
+ while (VirtualQueryEx(process_, base_address, &mbi, sizeof(mbi)) ==
+ sizeof(mbi)) {
+ if (mbi.State == MEM_COMMIT) {
+ if (mbi.Type == MEM_PRIVATE) {
+ committed_private += mbi.RegionSize;
+ } else if (mbi.Type == MEM_MAPPED) {
+ committed_mapped += mbi.RegionSize;
+ } else if (mbi.Type == MEM_IMAGE) {
+ committed_image += mbi.RegionSize;
+ } else {
+ NOTREACHED();
}
- base_address = (static_cast<BYTE*>(mbi.BaseAddress)) + mbi.RegionSize;
+ }
+ void* new_base = (static_cast<BYTE*>(mbi.BaseAddress)) + mbi.RegionSize;
+ // Avoid infinite loop by weird MEMORY_BASIC_INFORMATION.
+ // If we query 64bit processes in a 32bit process, VirtualQueryEx()
+ // returns such data.
+ if (new_base <= base_address) {
+ usage->image = 0;
+ usage->mapped = 0;
+ usage->priv = 0;
+ return;
+ }
+ base_address = new_base;
}
usage->image = committed_image / 1024;
usage->mapped = committed_mapped / 1024;
diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc
index a6dc4dc..362bedc 100644
--- a/chrome/browser/memory_details.cc
+++ b/chrome/browser/memory_details.cc
@@ -19,12 +19,14 @@ class RenderViewHostDelegate;
// Template of static data we use for finding browser process information.
// These entries must match the ordering for MemoryDetails::BrowserProcess.
-static ProcessData g_process_template[] = {
+static ProcessData
+ g_process_template[MemoryDetails::MAX_BROWSERS] = {
{ L"Chromium", L"chrome.exe", },
{ L"IE", L"iexplore.exe", },
{ L"Firefox", L"firefox.exe", },
{ L"Opera", L"opera.exe", },
{ L"Safari", L"safari.exe", },
+ { L"IE (64bit)", L"iexplore.exe", },
};
@@ -89,41 +91,46 @@ void MemoryDetails::CollectProcessData(
DCHECK(MessageLoop::current() ==
ChromeThread::GetMessageLoop(ChromeThread::FILE));
- int array_size = 32;
- scoped_ptr_malloc<DWORD> process_list;
- DWORD bytes_used = 0;
- do {
- array_size *= 2;
- process_list.reset(static_cast<DWORD*>(
- realloc(process_list.release(), sizeof(DWORD) * array_size)));
- // EnumProcesses doesn't return an error if the array is too small.
- // We have to check if the return buffer is full, and if so, call it
- // again. See msdn docs for more info.
- if (!EnumProcesses(process_list.get(), array_size * sizeof(DWORD),
- &bytes_used)) {
- LOG(ERROR) << "EnumProcesses failed: " << GetLastError();
- return;
- }
- } while (bytes_used == (array_size * sizeof(DWORD)));
-
- int num_processes = bytes_used / sizeof(DWORD);
-
// Clear old data.
for (int index = 0; index < arraysize(g_process_template); index++)
process_data_[index].processes.clear();
- for (int index = 0; index < num_processes; index++) {
- int pid = process_list.get()[index];
- ScopedHandle handle(OpenProcess(
+ SYSTEM_INFO system_info;
+ GetNativeSystemInfo(&system_info);
+ bool is_64bit_os =
+ system_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
+
+ ScopedHandle snapshot(::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
+ PROCESSENTRY32 process_entry = {sizeof(PROCESSENTRY32)};
+ if (!snapshot.Get()) {
+ LOG(ERROR) << "CreateToolhelp32Snaphot failed: " << GetLastError();
+ return;
+ }
+ if (!::Process32First(snapshot, &process_entry)) {
+ LOG(ERROR) << "Process32First failed: " << GetLastError();
+ return;
+ }
+ do {
+ int pid = process_entry.th32ProcessID;
+ ScopedHandle handle(::OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid));
if (!handle.Get())
continue;
- TCHAR name[MAX_PATH];
- if (!GetModuleBaseName(handle, NULL, name, MAX_PATH - 1))
- continue;
+ bool is_64bit_process = false;
+ // IsWow64Process() returns FALSE for a 32bit process on a 32bit OS.
+ // We need to check if the real OS is 64bit.
+ if (is_64bit_os) {
+ BOOL is_wow64 = FALSE;
+ // IsWow64Process() is supported by Windows XP SP2 or later.
+ IsWow64Process(handle, &is_wow64);
+ is_64bit_process = !is_wow64;
+ }
for (int index2 = 0; index2 < arraysize(g_process_template); index2++) {
- if (_wcsicmp(process_data_[index2].process_name, name) != 0)
+ if (_wcsicmp(process_data_[index2].process_name,
+ process_entry.szExeFile) != 0)
continue;
+ if (index2 == IE_BROWSER && is_64bit_process)
+ continue; // Should use IE_64BIT_BROWSER
// Get Memory Information.
ProcessMemoryInformation info;
info.pid = pid;
@@ -138,9 +145,10 @@ void MemoryDetails::CollectProcessData(
metrics->GetWorkingSetKBytes(&info.working_set);
// Get Version Information.
- if (index2 == 0) { // Chrome
+ TCHAR name[MAX_PATH];
+ if (index2 == CHROME_BROWSER) {
scoped_ptr<FileVersionInfo> version_info(
- FileVersionInfo::CreateFileVersionInfoForCurrentModule());
+ FileVersionInfo::CreateFileVersionInfoForCurrentModule());
if (version_info != NULL)
info.version = version_info->file_version();
// Check if this is one of the child processes whose data we collected
@@ -155,7 +163,7 @@ void MemoryDetails::CollectProcessData(
} else if (GetModuleFileNameEx(handle, NULL, name, MAX_PATH - 1)) {
std::wstring str_name(name);
scoped_ptr<FileVersionInfo> version_info(
- FileVersionInfo::CreateFileVersionInfo(str_name));
+ FileVersionInfo::CreateFileVersionInfo(str_name));
if (version_info != NULL) {
info.version = version_info->product_version();
info.product_name = version_info->product_name();
@@ -166,7 +174,7 @@ void MemoryDetails::CollectProcessData(
process_data_[index2].processes.push_back(info);
break;
}
- }
+ } while (::Process32Next(snapshot, &process_entry));
// Finally return to the browser thread.
ui_loop_->PostTask(FROM_HERE,
diff --git a/chrome/browser/memory_details.h b/chrome/browser/memory_details.h
index 2725285..ddf5280 100644
--- a/chrome/browser/memory_details.h
+++ b/chrome/browser/memory_details.h
@@ -78,6 +78,7 @@ class MemoryDetails : public base::RefCountedThreadSafe<MemoryDetails> {
FIREFOX_BROWSER,
OPERA_BROWSER,
SAFARI_BROWSER,
+ IE_64BIT_BROWSER,
MAX_BROWSERS
} BrowserProcess;
diff --git a/chrome/browser/resources/about_memory.html b/chrome/browser/resources/about_memory.html
index 0c31cdd..08f24ce 100644
--- a/chrome/browser/resources/about_memory.html
+++ b/chrome/browser/resources/about_memory.html
@@ -330,6 +330,9 @@ function reload() {
function formatNumber(str) {
str += '';
+ if (str == '0') {
+ return 'N/A ';
+ }
var x = str.split('.');
var x1 = x[0];
var x2 = x.length > 1 ? '.' + x[1] : '';