meminfo: Add Smaps(), showmap and friends.
Needed by showmap and also android_s_Debug to classify each allocation
into multiple heaps.
The APIs added are:
ForEachVmaFromFile - Global API to parse a file expected to be in the
same format as /proc/<pid>/smaps and make a callback for each VMA found.
ProcMemInfo::ForEachVma - Same as 'ForEachVmaFromFile' but for a
ProcMemInfo object corresponding to a process(pid).
ProcMemInfo::Smaps - Wrapper to ProcMemInfo::ForEachVma, except the
function collects 'struct Vma' in a member vector and returns the
reference for the same.
Added showmap2 using the APIs and the corresponding tests the same time.
Bug: 111694435
Test: showmap_test.sh
Test: libmeminfo_test 1
Change-Id: I3065809cf94ecf3da88529809701035c47a8ce34
Signed-off-by: Sandeep Patil <[email protected]>
diff --git a/libmeminfo_test.cpp b/libmeminfo_test.cpp
index d5252e9..20ed3bf 100644
--- a/libmeminfo_test.cpp
+++ b/libmeminfo_test.cpp
@@ -365,6 +365,191 @@
EXPECT_EQ(stats.swap_pss, 70);
}
+TEST(TestProcMemInfo, ForEachVmaFromFileTest) {
+ std::string exec_dir = ::android::base::GetExecutableDirectory();
+ std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
+ ProcMemInfo proc_mem(pid);
+
+ std::vector<Vma> vmas;
+ auto collect_vmas = [&](const Vma& v) { vmas.push_back(v); };
+ ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas));
+
+ // Expect values to be equal to what we have in testdata1/smaps_short
+ // Check for sizes first
+ ASSERT_EQ(vmas[0].usage.vss, 32768);
+ EXPECT_EQ(vmas[1].usage.vss, 11204);
+ EXPECT_EQ(vmas[2].usage.vss, 16896);
+ EXPECT_EQ(vmas[3].usage.vss, 260);
+ EXPECT_EQ(vmas[4].usage.vss, 6060);
+ EXPECT_EQ(vmas[5].usage.vss, 4);
+
+ // Check for names
+ EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
+ EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
+ EXPECT_EQ(vmas[2].name, "[anon:libc_malloc]");
+ EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
+ EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
+ EXPECT_EQ(vmas[5].name, "[vsyscall]");
+
+ EXPECT_EQ(vmas[0].usage.rss, 2048);
+ EXPECT_EQ(vmas[1].usage.rss, 11188);
+ EXPECT_EQ(vmas[2].usage.rss, 15272);
+ EXPECT_EQ(vmas[3].usage.rss, 260);
+ EXPECT_EQ(vmas[4].usage.rss, 4132);
+ EXPECT_EQ(vmas[5].usage.rss, 0);
+
+ EXPECT_EQ(vmas[0].usage.pss, 113);
+ EXPECT_EQ(vmas[1].usage.pss, 2200);
+ EXPECT_EQ(vmas[2].usage.pss, 15272);
+ EXPECT_EQ(vmas[3].usage.pss, 260);
+ EXPECT_EQ(vmas[4].usage.pss, 1274);
+ EXPECT_EQ(vmas[5].usage.pss, 0);
+
+ EXPECT_EQ(vmas[0].usage.uss, 0);
+ EXPECT_EQ(vmas[1].usage.uss, 1660);
+ EXPECT_EQ(vmas[2].usage.uss, 15272);
+ EXPECT_EQ(vmas[3].usage.uss, 260);
+ EXPECT_EQ(vmas[4].usage.uss, 0);
+ EXPECT_EQ(vmas[5].usage.uss, 0);
+
+ EXPECT_EQ(vmas[0].usage.private_clean, 0);
+ EXPECT_EQ(vmas[1].usage.private_clean, 0);
+ EXPECT_EQ(vmas[2].usage.private_clean, 0);
+ EXPECT_EQ(vmas[3].usage.private_clean, 260);
+ EXPECT_EQ(vmas[4].usage.private_clean, 0);
+ EXPECT_EQ(vmas[5].usage.private_clean, 0);
+
+ EXPECT_EQ(vmas[0].usage.private_dirty, 0);
+ EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
+ EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
+ EXPECT_EQ(vmas[3].usage.private_dirty, 0);
+ EXPECT_EQ(vmas[4].usage.private_dirty, 0);
+ EXPECT_EQ(vmas[5].usage.private_dirty, 0);
+
+ EXPECT_EQ(vmas[0].usage.shared_clean, 0);
+ EXPECT_EQ(vmas[1].usage.shared_clean, 80);
+ EXPECT_EQ(vmas[2].usage.shared_clean, 0);
+ EXPECT_EQ(vmas[3].usage.shared_clean, 0);
+ EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
+ EXPECT_EQ(vmas[5].usage.shared_clean, 0);
+
+ EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
+ EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
+ EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
+ EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
+ EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
+ EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
+
+ EXPECT_EQ(vmas[0].usage.swap, 0);
+ EXPECT_EQ(vmas[1].usage.swap, 0);
+ EXPECT_EQ(vmas[2].usage.swap, 0);
+ EXPECT_EQ(vmas[3].usage.swap, 0);
+ EXPECT_EQ(vmas[4].usage.swap, 0);
+ EXPECT_EQ(vmas[5].usage.swap, 0);
+
+ EXPECT_EQ(vmas[0].usage.swap_pss, 0);
+ EXPECT_EQ(vmas[1].usage.swap_pss, 0);
+ EXPECT_EQ(vmas[2].usage.swap_pss, 0);
+ EXPECT_EQ(vmas[3].usage.swap_pss, 0);
+ EXPECT_EQ(vmas[4].usage.swap_pss, 0);
+ EXPECT_EQ(vmas[5].usage.swap_pss, 0);
+}
+
+TEST(TestProcMemInfo, SmapsReturnTest) {
+ ProcMemInfo proc_mem(pid);
+ auto vmas = proc_mem.Smaps();
+ EXPECT_FALSE(vmas.empty());
+}
+
+TEST(TestProcMemInfo, SmapsTest) {
+ std::string exec_dir = ::android::base::GetExecutableDirectory();
+ std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
+ ProcMemInfo proc_mem(pid);
+ auto vmas = proc_mem.Smaps(path);
+
+ ASSERT_FALSE(vmas.empty());
+
+ // Expect values to be equal to what we have in testdata1/smaps_short
+ // Check for sizes first
+ ASSERT_EQ(vmas[0].usage.vss, 32768);
+ EXPECT_EQ(vmas[1].usage.vss, 11204);
+ EXPECT_EQ(vmas[2].usage.vss, 16896);
+ EXPECT_EQ(vmas[3].usage.vss, 260);
+ EXPECT_EQ(vmas[4].usage.vss, 6060);
+ EXPECT_EQ(vmas[5].usage.vss, 4);
+
+ // Check for names
+ EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
+ EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
+ EXPECT_EQ(vmas[2].name, "[anon:libc_malloc]");
+ EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
+ EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
+ EXPECT_EQ(vmas[5].name, "[vsyscall]");
+
+ EXPECT_EQ(vmas[0].usage.rss, 2048);
+ EXPECT_EQ(vmas[1].usage.rss, 11188);
+ EXPECT_EQ(vmas[2].usage.rss, 15272);
+ EXPECT_EQ(vmas[3].usage.rss, 260);
+ EXPECT_EQ(vmas[4].usage.rss, 4132);
+ EXPECT_EQ(vmas[5].usage.rss, 0);
+
+ EXPECT_EQ(vmas[0].usage.pss, 113);
+ EXPECT_EQ(vmas[1].usage.pss, 2200);
+ EXPECT_EQ(vmas[2].usage.pss, 15272);
+ EXPECT_EQ(vmas[3].usage.pss, 260);
+ EXPECT_EQ(vmas[4].usage.pss, 1274);
+ EXPECT_EQ(vmas[5].usage.pss, 0);
+
+ EXPECT_EQ(vmas[0].usage.uss, 0);
+ EXPECT_EQ(vmas[1].usage.uss, 1660);
+ EXPECT_EQ(vmas[2].usage.uss, 15272);
+ EXPECT_EQ(vmas[3].usage.uss, 260);
+ EXPECT_EQ(vmas[4].usage.uss, 0);
+ EXPECT_EQ(vmas[5].usage.uss, 0);
+
+ EXPECT_EQ(vmas[0].usage.private_clean, 0);
+ EXPECT_EQ(vmas[1].usage.private_clean, 0);
+ EXPECT_EQ(vmas[2].usage.private_clean, 0);
+ EXPECT_EQ(vmas[3].usage.private_clean, 260);
+ EXPECT_EQ(vmas[4].usage.private_clean, 0);
+ EXPECT_EQ(vmas[5].usage.private_clean, 0);
+
+ EXPECT_EQ(vmas[0].usage.private_dirty, 0);
+ EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
+ EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
+ EXPECT_EQ(vmas[3].usage.private_dirty, 0);
+ EXPECT_EQ(vmas[4].usage.private_dirty, 0);
+ EXPECT_EQ(vmas[5].usage.private_dirty, 0);
+
+ EXPECT_EQ(vmas[0].usage.shared_clean, 0);
+ EXPECT_EQ(vmas[1].usage.shared_clean, 80);
+ EXPECT_EQ(vmas[2].usage.shared_clean, 0);
+ EXPECT_EQ(vmas[3].usage.shared_clean, 0);
+ EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
+ EXPECT_EQ(vmas[5].usage.shared_clean, 0);
+
+ EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
+ EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
+ EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
+ EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
+ EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
+ EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
+
+ EXPECT_EQ(vmas[0].usage.swap, 0);
+ EXPECT_EQ(vmas[1].usage.swap, 0);
+ EXPECT_EQ(vmas[2].usage.swap, 0);
+ EXPECT_EQ(vmas[3].usage.swap, 0);
+ EXPECT_EQ(vmas[4].usage.swap, 0);
+ EXPECT_EQ(vmas[5].usage.swap, 0);
+
+ EXPECT_EQ(vmas[0].usage.swap_pss, 0);
+ EXPECT_EQ(vmas[1].usage.swap_pss, 0);
+ EXPECT_EQ(vmas[2].usage.swap_pss, 0);
+ EXPECT_EQ(vmas[3].usage.swap_pss, 0);
+ EXPECT_EQ(vmas[4].usage.swap_pss, 0);
+ EXPECT_EQ(vmas[5].usage.swap_pss, 0);
+}
+
TEST(ValidateProcMemInfoFlags, TestPageFlags1) {
// Create proc object using libpagemap
pm_kernel_t* ker;