summaryrefslogtreecommitdiffstats
path: root/base/process_util_linux.cc
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-04 22:26:03 +0000
committerthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-04 22:26:03 +0000
commit7dcac98e5b38a32ac69c75ff16af6b6b1ee46494 (patch)
treeaf19dbd73aae069a5db0f1bc4824e87c663ab8ac /base/process_util_linux.cc
parent3ee84160f356ad78f48639b4e26eebee9a88b9c1 (diff)
downloadchromium_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/process_util_linux.cc')
-rw-r--r--base/process_util_linux.cc78
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;