Log when removing targets because of low RSS.
Bug: 156495337
Change-Id: I8b0ed7593c9809131edc61e56358ca0c140e68cf
diff --git a/src/profiling/common/proc_utils.cc b/src/profiling/common/proc_utils.cc
index 8a9561a..155d091 100644
--- a/src/profiling/common/proc_utils.cc
+++ b/src/profiling/common/proc_utils.cc
@@ -153,7 +153,7 @@
});
}
-base::Optional<uint32_t> GetRssAnonAndSwap(pid_t pid) {
+base::Optional<std::string> ReadStatus(pid_t pid) {
std::string path = "/proc/" + std::to_string(pid) + "/status";
std::string status;
bool read_proc = base::ReadFile(path, &status);
@@ -161,6 +161,10 @@
PERFETTO_ELOG("Failed to read %s", path.c_str());
return base::nullopt;
}
+ return base::Optional<std::string>(status);
+}
+
+base::Optional<uint32_t> GetRssAnonAndSwap(const std::string& status) {
auto anon_rss = ParseProcStatusSize(status, "RssAnon:");
auto swap = ParseProcStatusSize(status, "VmSwap:");
if (anon_rss.has_value() && swap.has_value()) {
@@ -171,8 +175,17 @@
void RemoveUnderAnonThreshold(uint32_t min_size_kb, std::set<pid_t>* pids) {
for (auto it = pids->begin(); it != pids->end();) {
- base::Optional<uint32_t> rss_and_swap = GetRssAnonAndSwap(*it);
+ const pid_t pid = *it;
+
+ base::Optional<std::string> status = ReadStatus(pid);
+ base::Optional<uint32_t> rss_and_swap;
+ if (status)
+ rss_and_swap = GetRssAnonAndSwap(*status);
+
if (rss_and_swap && rss_and_swap < min_size_kb) {
+ PERFETTO_LOG("Removing pid %d from profiled set (anon: %d kB < %" PRIu32
+ ")",
+ pid, *rss_and_swap, min_size_kb);
it = pids->erase(it);
} else {
++it;
@@ -180,21 +193,5 @@
}
}
-bool IsUnderAnonRssAndSwapThreshold(pid_t pid,
- uint32_t min_size_kb,
- const std::string& status) {
- auto anon_rss = ParseProcStatusSize(status, "RssAnon:");
- auto swap = ParseProcStatusSize(status, "VmSwap:");
- if (anon_rss.has_value() && swap.has_value()) {
- uint32_t anon_kb = anon_rss.value() + swap.value();
- if (anon_kb < min_size_kb) {
- PERFETTO_LOG("Removing pid %d from profiled set (anon: %d kB)", pid,
- anon_kb);
- return true;
- }
- }
- return false;
-}
-
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/common/proc_utils.h b/src/profiling/common/proc_utils.h
index c658ead..61c35b4 100644
--- a/src/profiling/common/proc_utils.h
+++ b/src/profiling/common/proc_utils.h
@@ -52,13 +52,11 @@
std::set<pid_t>* pids);
bool GetCmdlineForPID(pid_t pid, std::string* name);
-base::Optional<uint32_t> GetRssAnonAndSwap(pid_t pid);
+base::Optional<std::string> ReadStatus(pid_t pid);
+base::Optional<uint32_t> GetRssAnonAndSwap(const std::string&);
// Filters the list of pids (in-place), keeping only the
// entries satisfying the minimum size criteria for anonymous memory.
void RemoveUnderAnonThreshold(uint32_t min_size_kb, std::set<pid_t>* pids);
-bool IsUnderAnonRssAndSwapThreshold(pid_t pid,
- uint32_t min_size_kb,
- const std::string& status);
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/common/proc_utils_unittest.cc b/src/profiling/common/proc_utils_unittest.cc
index 3d049f9..f16c834 100644
--- a/src/profiling/common/proc_utils_unittest.cc
+++ b/src/profiling/common/proc_utils_unittest.cc
@@ -125,16 +125,15 @@
PERFETTO_CHECK(PERFETTO_EINTR(waitpid(pid, nullptr, 0)) == pid);
}
-TEST(ProcUtilsTest, AnonThreshold) {
+TEST(ProcUtilsTest, GetRssAnonAndSwap) {
std::string status = "Name: foo\nRssAnon: 10000 kB\nVmSwap:\t10000 kB";
- EXPECT_FALSE(IsUnderAnonRssAndSwapThreshold(123, 20000, status));
- EXPECT_TRUE(IsUnderAnonRssAndSwapThreshold(123, 20001, status));
+ EXPECT_EQ(GetRssAnonAndSwap(status), 20000u);
}
-TEST(ProcUtilsTest, AnonThresholdInvalidInput) {
- EXPECT_FALSE(IsUnderAnonRssAndSwapThreshold(123, 20000, ""));
- EXPECT_FALSE(IsUnderAnonRssAndSwapThreshold(123, 20000, "RssAnon: 10000 kB"));
- EXPECT_FALSE(IsUnderAnonRssAndSwapThreshold(123, 20000, "VmSwap: 10000 kB"));
+TEST(ProcUtilsTest, GetRssAnonAndSwapInvalidInput) {
+ EXPECT_EQ(GetRssAnonAndSwap(""), base::nullopt);
+ EXPECT_EQ(GetRssAnonAndSwap("RssAnon: 10000 kB"), base::nullopt);
+ EXPECT_EQ(GetRssAnonAndSwap("VmSwap: 10000"), base::nullopt);
}
} // namespace
} // namespace profiling
diff --git a/src/profiling/memory/heapprofd_producer.cc b/src/profiling/memory/heapprofd_producer.cc
index a335a19..267f300 100644
--- a/src/profiling/memory/heapprofd_producer.cc
+++ b/src/profiling/memory/heapprofd_producer.cc
@@ -1134,7 +1134,11 @@
if (!any_guardrail)
return;
- base::Optional<uint32_t> anon_and_swap = GetRssAnonAndSwap(getpid());
+ base::Optional<uint32_t> anon_and_swap;
+ base::Optional<std::string> status = ReadStatus(getpid());
+ if (status)
+ anon_and_swap = GetRssAnonAndSwap(*status);
+
if (!anon_and_swap) {
PERFETTO_ELOG("Failed to read heapprofd memory.");
return;