diff options
author | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-04 22:26:03 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-04 22:26:03 +0000 |
commit | 7dcac98e5b38a32ac69c75ff16af6b6b1ee46494 (patch) | |
tree | af19dbd73aae069a5db0f1bc4824e87c663ab8ac /base | |
parent | 3ee84160f356ad78f48639b4e26eebee9a88b9c1 (diff) | |
download | chromium_src-7dcac98e5b38a32ac69c75ff16af6b6b1ee46494.zip chromium_src-7dcac98e5b38a32ac69c75ff16af6b6b1ee46494.tar.gz chromium_src-7dcac98e5b38a32ac69c75ff16af6b6b1ee46494.tar.bz2 |
Linux: use /proc/pid/statm to get memory stats when /proc/pid/smaps is unavailable.
BUG=23258
TEST=We get approximate memory usage in about:memory for sandboxed renderers.
Review URL: http://codereview.chromium.org/365007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31019 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/process_util_linux.cc | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/base/process_util_linux.cc b/base/process_util_linux.cc index 6f3d910..7c78f6f 100644 --- a/base/process_util_linux.cc +++ b/base/process_util_linux.cc @@ -14,8 +14,6 @@ #include <time.h> #include <unistd.h> -#include <string> - #include "base/file_util.h" #include "base/logging.h" #include "base/string_tokenizer.h" @@ -253,8 +251,10 @@ size_t ProcessMetrics::GetPrivateBytes() const { return ws_usage.priv << 10; } -// Private and Shared working set sizes are obtained from /proc/<pid>/smaps, -// as in http://www.pixelbeat.org/scripts/ps_mem.py +// Private and Shared working set sizes are obtained from /proc/<pid>/smaps. +// When that's not available, use the values from /proc<pid>/statm as a +// close approximation. +// See http://www.pixelbeat.org/scripts/ps_mem.py bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { FilePath stat_file = FilePath("/proc").Append(IntToString(process_)).Append("smaps"); @@ -262,32 +262,50 @@ bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { int private_kb = 0; int pss_kb = 0; bool have_pss = false; - if (!file_util::ReadFileToString(stat_file, &smaps) || smaps.length() == 0) - return false; - - StringTokenizer tokenizer(smaps, ":\n"); - ParsingState state = KEY_NAME; - std::string last_key_name; - while (tokenizer.GetNext()) { - switch (state) { - case KEY_NAME: - last_key_name = tokenizer.token(); - state = KEY_VALUE; - break; - case KEY_VALUE: - if (last_key_name.empty()) { - NOTREACHED(); - return false; - } - if (StartsWithASCII(last_key_name, "Private_", 1)) { - private_kb += StringToInt(tokenizer.token()); - } else if (StartsWithASCII(last_key_name, "Pss", 1)) { - have_pss = true; - pss_kb += StringToInt(tokenizer.token()); - } - state = KEY_NAME; - break; + if (file_util::ReadFileToString(stat_file, &smaps) && smaps.length() > 0) { + StringTokenizer tokenizer(smaps, ":\n"); + ParsingState state = KEY_NAME; + std::string last_key_name; + while (tokenizer.GetNext()) { + switch (state) { + case KEY_NAME: + last_key_name = tokenizer.token(); + state = KEY_VALUE; + break; + case KEY_VALUE: + if (last_key_name.empty()) { + NOTREACHED(); + return false; + } + if (StartsWithASCII(last_key_name, "Private_", 1)) { + private_kb += StringToInt(tokenizer.token()); + } else if (StartsWithASCII(last_key_name, "Pss", 1)) { + have_pss = true; + pss_kb += StringToInt(tokenizer.token()); + } + state = KEY_NAME; + break; + } } + } else { + // Try statm if smaps is empty because of the SUID sandbox. + // First we need to get the page size though. + int page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; + if (page_size_kb <= 0) + return false; + + stat_file = + FilePath("/proc").Append(IntToString(process_)).Append("statm"); + std::string statm; + if (!file_util::ReadFileToString(stat_file, &statm) || statm.length() == 0) + return false; + + std::vector<std::string> statm_vec; + SplitString(statm, ' ', &statm_vec); + if (statm_vec.size() != 7) + return false; // Not the format we expect. + private_kb = StringToInt(statm_vec[1]) - StringToInt(statm_vec[2]); + private_kb *= page_size_kb; } ws_usage->priv = private_kb; // Sharable is not calculated, as it does not provide interesting data. @@ -414,7 +432,7 @@ int ProcessMetrics::GetCPUUsage() { } int64 time_delta = time - last_time_; - DCHECK(time_delta != 0); + DCHECK_NE(time_delta, 0); if (time_delta == 0) return 0; |