• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <sys/mman.h>
18 #include <sys/types.h>
19 #include <sys/wait.h>
20 #include <unistd.h>
21 
22 #include <gtest/gtest.h>
23 
24 #include <filesystem>
25 #include <string>
26 #include <vector>
27 
28 #include <meminfo/androidprocheaps.h>
29 #include <meminfo/pageacct.h>
30 #include <meminfo/procmeminfo.h>
31 #include <meminfo/sysmeminfo.h>
32 #include <vintf/VintfObject.h>
33 
34 #include <android-base/file.h>
35 #include <android-base/logging.h>
36 #include <android-base/properties.h>
37 #include <android-base/stringprintf.h>
38 #include <android-base/strings.h>
39 
40 using namespace std;
41 using namespace android::meminfo;
42 using android::vintf::KernelVersion;
43 using android::vintf::RuntimeInfo;
44 using android::vintf::VintfObject;
45 
46 namespace fs = std::filesystem;
47 
48 pid_t pid = -1;
49 
TEST(ProcMemInfo,TestWorkingTestReset)50 TEST(ProcMemInfo, TestWorkingTestReset) {
51     // Expect reset to succeed
52     EXPECT_TRUE(ProcMemInfo::ResetWorkingSet(pid));
53 }
54 
TEST(ProcMemInfo,UsageEmpty)55 TEST(ProcMemInfo, UsageEmpty) {
56     // If we created the object for getting working set,
57     // the usage must be empty
58     ProcMemInfo proc_mem(pid, true);
59     const MemUsage& usage = proc_mem.Usage();
60     EXPECT_EQ(usage.rss, 0);
61     EXPECT_EQ(usage.vss, 0);
62     EXPECT_EQ(usage.pss, 0);
63     EXPECT_EQ(usage.uss, 0);
64     EXPECT_EQ(usage.swap, 0);
65 }
66 
TEST(ProcMemInfo,MapsNotEmpty)67 TEST(ProcMemInfo, MapsNotEmpty) {
68     // Make sure the process maps are never empty
69     ProcMemInfo proc_mem(pid);
70     const std::vector<Vma>& maps = proc_mem.Maps();
71     EXPECT_FALSE(maps.empty());
72 }
73 
TEST(ProcMemInfo,MapsUsageNotEmpty)74 TEST(ProcMemInfo, MapsUsageNotEmpty) {
75     ProcMemInfo proc_mem(pid);
76     const std::vector<Vma>& maps = proc_mem.Maps();
77     EXPECT_FALSE(maps.empty());
78     uint64_t total_pss = 0;
79     uint64_t total_rss = 0;
80     uint64_t total_uss = 0;
81     for (auto& map : maps) {
82         ASSERT_NE(0, map.usage.vss);
83         total_rss += map.usage.rss;
84         total_pss += map.usage.pss;
85         total_uss += map.usage.uss;
86     }
87 
88     // Crude check that stats are actually being read.
89     EXPECT_NE(0, total_rss) << "RSS zero for all maps, that is not possible.";
90     EXPECT_NE(0, total_pss) << "PSS zero for all maps, that is not possible.";
91     EXPECT_NE(0, total_uss) << "USS zero for all maps, that is not possible.";
92 }
93 
TEST(ProcMemInfo,MapsUsageEmpty)94 TEST(ProcMemInfo, MapsUsageEmpty) {
95     ProcMemInfo proc_mem(pid);
96     const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
97     EXPECT_FALSE(maps.empty());
98     // Verify that all usage stats are zero in every map.
99     for (auto& map : maps) {
100         ASSERT_EQ(0, map.usage.vss);
101         ASSERT_EQ(0, map.usage.rss);
102         ASSERT_EQ(0, map.usage.pss);
103         ASSERT_EQ(0, map.usage.uss);
104         ASSERT_EQ(0, map.usage.swap);
105         ASSERT_EQ(0, map.usage.swap_pss);
106         ASSERT_EQ(0, map.usage.private_clean);
107         ASSERT_EQ(0, map.usage.private_dirty);
108         ASSERT_EQ(0, map.usage.shared_clean);
109         ASSERT_EQ(0, map.usage.shared_dirty);
110     }
111 }
112 
TEST(ProcMemInfo,MapsUsageFillInLater)113 TEST(ProcMemInfo, MapsUsageFillInLater) {
114     ProcMemInfo proc_mem(pid);
115     const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
116     EXPECT_FALSE(maps.empty());
117     for (auto& map : maps) {
118         Vma update_map(map);
119         ASSERT_EQ(map.start, update_map.start);
120         ASSERT_EQ(map.end, update_map.end);
121         ASSERT_EQ(map.offset, update_map.offset);
122         ASSERT_EQ(map.flags, update_map.flags);
123         ASSERT_EQ(map.name, update_map.name);
124         ASSERT_EQ(0, update_map.usage.vss);
125         ASSERT_EQ(0, update_map.usage.rss);
126         ASSERT_EQ(0, update_map.usage.pss);
127         ASSERT_EQ(0, update_map.usage.uss);
128         ASSERT_EQ(0, update_map.usage.swap);
129         ASSERT_EQ(0, update_map.usage.swap_pss);
130         ASSERT_EQ(0, update_map.usage.private_clean);
131         ASSERT_EQ(0, update_map.usage.private_dirty);
132         ASSERT_EQ(0, update_map.usage.shared_clean);
133         ASSERT_EQ(0, update_map.usage.shared_dirty);
134         ASSERT_TRUE(proc_mem.FillInVmaStats(update_map));
135         // Check that at least one usage stat was updated.
136         ASSERT_NE(0, update_map.usage.vss);
137     }
138 }
139 
TEST(ProcMemInfo,MapsUsageFillInAll)140 TEST(ProcMemInfo, MapsUsageFillInAll) {
141     ProcMemInfo proc_mem(pid);
142     const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
143     EXPECT_FALSE(maps.empty());
144     for (auto& map : maps) {
145         ASSERT_EQ(0, map.usage.vss);
146         ASSERT_EQ(0, map.usage.rss);
147         ASSERT_EQ(0, map.usage.pss);
148         ASSERT_EQ(0, map.usage.uss);
149         ASSERT_EQ(0, map.usage.swap);
150         ASSERT_EQ(0, map.usage.swap_pss);
151         ASSERT_EQ(0, map.usage.private_clean);
152         ASSERT_EQ(0, map.usage.private_dirty);
153         ASSERT_EQ(0, map.usage.shared_clean);
154         ASSERT_EQ(0, map.usage.shared_dirty);
155     }
156     // GetUsageStats' non-default parameter get_wss is false by default in
157     // ProcMemInfo's constructor.
158     ASSERT_TRUE(proc_mem.GetUsageStats(false));
159     for (auto& map : maps) {
160         // Check that at least one usage stat was updated.
161         ASSERT_NE(0, map.usage.vss);
162     }
163 }
164 
TEST(ProcMemInfo,PageMapPresent)165 TEST(ProcMemInfo, PageMapPresent) {
166     static constexpr size_t kNumPages = 20;
167     size_t pagesize = getpagesize();
168     void* ptr = mmap(nullptr, pagesize * (kNumPages + 2), PROT_READ | PROT_WRITE,
169                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
170     ASSERT_NE(MAP_FAILED, ptr);
171 
172     // Unmap the first page and the last page so that we guarantee this
173     // map is in a map by itself.
174     ASSERT_EQ(0, munmap(ptr, pagesize));
175     uintptr_t addr = reinterpret_cast<uintptr_t>(ptr) + pagesize;
176     ASSERT_EQ(0, munmap(reinterpret_cast<void*>(addr + kNumPages * pagesize), pagesize));
177 
178     ProcMemInfo proc_mem(getpid());
179     const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
180     ASSERT_FALSE(maps.empty());
181 
182     // Find the vma associated with our previously created map.
183     const Vma* test_vma = nullptr;
184     for (const Vma& vma : maps) {
185         if (vma.start == addr) {
186             test_vma = &vma;
187             break;
188         }
189     }
190     ASSERT_TRUE(test_vma != nullptr) << "Cannot find test map.";
191 
192     // Verify that none of the pages are listed as present.
193     std::vector<uint64_t> pagemap;
194     ASSERT_TRUE(proc_mem.PageMap(*test_vma, &pagemap));
195     ASSERT_EQ(kNumPages, pagemap.size());
196     for (size_t i = 0; i < pagemap.size(); i++) {
197         EXPECT_FALSE(android::meminfo::page_present(pagemap[i]))
198                 << "Page " << i << " is present and it should not be.";
199     }
200 
201     // Make some of the pages present and verify that we see them
202     // as present.
203     uint8_t* data = reinterpret_cast<uint8_t*>(addr);
204     data[0] = 1;
205     data[pagesize * 5] = 1;
206     data[pagesize * 11] = 1;
207 
208     ASSERT_TRUE(proc_mem.PageMap(*test_vma, &pagemap));
209     ASSERT_EQ(kNumPages, pagemap.size());
210     for (size_t i = 0; i < pagemap.size(); i++) {
211         if (i == 0 || i == 5 || i == 11) {
212             EXPECT_TRUE(android::meminfo::page_present(pagemap[i]))
213                     << "Page " << i << " is not present and it should be.";
214         } else {
215             EXPECT_FALSE(android::meminfo::page_present(pagemap[i]))
216                     << "Page " << i << " is present and it should not be.";
217         }
218     }
219 
220     ASSERT_EQ(0, munmap(reinterpret_cast<void*>(addr), kNumPages * pagesize));
221 }
222 
TEST(ProcMemInfo,WssEmpty)223 TEST(ProcMemInfo, WssEmpty) {
224     // If we created the object for getting usage,
225     // the working set must be empty
226     ProcMemInfo proc_mem(pid, false);
227     const MemUsage& wss = proc_mem.Wss();
228     EXPECT_EQ(wss.rss, 0);
229     EXPECT_EQ(wss.vss, 0);
230     EXPECT_EQ(wss.pss, 0);
231     EXPECT_EQ(wss.uss, 0);
232     EXPECT_EQ(wss.swap, 0);
233 }
234 
TEST(ProcMemInfo,SwapOffsetsEmpty)235 TEST(ProcMemInfo, SwapOffsetsEmpty) {
236     // If we created the object for getting working set,
237     // the swap offsets must be empty
238     ProcMemInfo proc_mem(pid, true);
239     const std::vector<uint64_t>& swap_offsets = proc_mem.SwapOffsets();
240     EXPECT_EQ(swap_offsets.size(), 0);
241 }
242 
TEST(ProcMemInfo,IsSmapsSupportedTest)243 TEST(ProcMemInfo, IsSmapsSupportedTest) {
244     // Check if /proc/self/smaps_rollup exists using the API.
245     bool supported = IsSmapsRollupSupported();
246     EXPECT_EQ(!access("/proc/self/smaps_rollup", F_OK | R_OK), supported);
247 }
248 
TEST(ProcMemInfo,SmapsOrRollupTest)249 TEST(ProcMemInfo, SmapsOrRollupTest) {
250     // Make sure we can parse 'smaps_rollup' correctly
251     std::string rollup =
252             R"rollup(12c00000-7fe859e000 ---p 00000000 00:00 0                                [rollup]
253 Rss:              331908 kB
254 Pss:              202052 kB
255 Shared_Clean:     158492 kB
256 Shared_Dirty:      18928 kB
257 Private_Clean:     90472 kB
258 Private_Dirty:     64016 kB
259 Referenced:       318700 kB
260 Anonymous:         81984 kB
261 AnonHugePages:         0 kB
262 Shared_Hugetlb:        0 kB
263 Private_Hugetlb:       0 kB
264 Swap:               5344 kB
265 SwapPss:             442 kB
266 Locked:          1523537 kB)rollup";
267 
268     TemporaryFile tf;
269     ASSERT_TRUE(tf.fd != -1);
270     ASSERT_TRUE(::android::base::WriteStringToFd(rollup, tf.fd));
271 
272     MemUsage stats;
273     ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
274     EXPECT_EQ(stats.rss, 331908);
275     EXPECT_EQ(stats.pss, 202052);
276     EXPECT_EQ(stats.uss, 154488);
277     EXPECT_EQ(stats.private_clean, 90472);
278     EXPECT_EQ(stats.private_dirty, 64016);
279     EXPECT_EQ(stats.swap_pss, 442);
280 }
281 
TEST(ProcMemInfo,SmapsOrRollupSmapsTest)282 TEST(ProcMemInfo, SmapsOrRollupSmapsTest) {
283     // Make sure /proc/<pid>/smaps is parsed correctly
284     std::string smaps =
285             R"smaps(12c00000-13440000 rw-p 00000000 00:00 0                                  [anon:dalvik-main space (region space)]
286 Name:           [anon:dalvik-main space (region space)]
287 Size:               8448 kB
288 KernelPageSize:        4 kB
289 MMUPageSize:           4 kB
290 Rss:                2652 kB
291 Pss:                2652 kB
292 Shared_Clean:        840 kB
293 Shared_Dirty:         40 kB
294 Private_Clean:        84 kB
295 Private_Dirty:      2652 kB
296 Referenced:         2652 kB
297 Anonymous:          2652 kB
298 AnonHugePages:         0 kB
299 ShmemPmdMapped:        0 kB
300 Shared_Hugetlb:        0 kB
301 Private_Hugetlb:       0 kB
302 Swap:                102 kB
303 SwapPss:              70 kB
304 Locked:             2652 kB
305 VmFlags: rd wr mr mw me ac
306 )smaps";
307 
308     TemporaryFile tf;
309     ASSERT_TRUE(tf.fd != -1);
310     ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
311 
312     MemUsage stats;
313     ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
314     EXPECT_EQ(stats.rss, 2652);
315     EXPECT_EQ(stats.pss, 2652);
316     EXPECT_EQ(stats.uss, 2736);
317     EXPECT_EQ(stats.private_clean, 84);
318     EXPECT_EQ(stats.private_dirty, 2652);
319     EXPECT_EQ(stats.swap_pss, 70);
320 }
321 
TEST(ProcMemInfo,SmapsOrRollupPssRollupTest)322 TEST(ProcMemInfo, SmapsOrRollupPssRollupTest) {
323     // Make sure /proc/<pid>/smaps is parsed correctly
324     // to get the PSS
325     std::string smaps =
326             R"smaps(12c00000-13440000 rw-p 00000000 00:00 0                                  [anon:dalvik-main space (region space)]
327 Name:           [anon:dalvik-main space (region space)]
328 Size:               8448 kB
329 KernelPageSize:        4 kB
330 MMUPageSize:           4 kB
331 Rss:                2652 kB
332 Pss:                2652 kB
333 Shared_Clean:        840 kB
334 Shared_Dirty:         40 kB
335 Private_Clean:        84 kB
336 Private_Dirty:      2652 kB
337 Referenced:         2652 kB
338 Anonymous:          2652 kB
339 AnonHugePages:         0 kB
340 ShmemPmdMapped:        0 kB
341 Shared_Hugetlb:        0 kB
342 Private_Hugetlb:       0 kB
343 Swap:                102 kB
344 SwapPss:              70 kB
345 Locked:             2652 kB
346 VmFlags: rd wr mr mw me ac
347 )smaps";
348 
349     TemporaryFile tf;
350     ASSERT_TRUE(tf.fd != -1);
351     ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
352 
353     uint64_t pss;
354     ASSERT_EQ(SmapsOrRollupPssFromFile(tf.path, &pss), true);
355     EXPECT_EQ(pss, 2652);
356 }
357 
TEST(ProcMemInfo,SmapsOrRollupPssSmapsTest)358 TEST(ProcMemInfo, SmapsOrRollupPssSmapsTest) {
359     // Correctly parse smaps file to gather pss
360     std::string exec_dir = ::android::base::GetExecutableDirectory();
361     std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
362 
363     uint64_t pss;
364     ASSERT_EQ(SmapsOrRollupPssFromFile(path, &pss), true);
365     EXPECT_EQ(pss, 19119);
366 }
367 
TEST(ProcMemInfo,StatusVmRSSTest)368 TEST(ProcMemInfo, StatusVmRSSTest) {
369     std::string exec_dir = ::android::base::GetExecutableDirectory();
370     std::string path = ::android::base::StringPrintf("%s/testdata1/status", exec_dir.c_str());
371 
372     uint64_t rss;
373     ASSERT_EQ(StatusVmRSSFromFile(path, &rss), true);
374     EXPECT_EQ(rss, 730764);
375 }
376 
TEST(ProcMemInfo,StatusVmRSSBogusFileTest)377 TEST(ProcMemInfo, StatusVmRSSBogusFileTest) {
378     std::string exec_dir = ::android::base::GetExecutableDirectory();
379     std::string path = ::android::base::StringPrintf("%s/testdata1/smaps", exec_dir.c_str());
380 
381     uint64_t rss;
382     ASSERT_EQ(StatusVmRSSFromFile(path, &rss), false);
383 }
384 
TEST(ProcMemInfo,ForEachExistingVmaTest)385 TEST(ProcMemInfo, ForEachExistingVmaTest) {
386     std::string exec_dir = ::android::base::GetExecutableDirectory();
387     std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
388     ProcMemInfo proc_mem(pid);
389     // Populate maps_.
390     proc_mem.Smaps(path);
391     std::vector<Vma> vmas;
392     auto collect_vmas = [&](const Vma& v) {
393         vmas.push_back(v);
394         return true;
395     };
396     EXPECT_TRUE(proc_mem.ForEachExistingVma(collect_vmas));
397 
398     // The size of vmas is not checked because Smaps() will return 5 vmas on x86
399     // and 6 vmas otherwise, as [vsyscall] is not processed on x86.
400 
401     // Expect values to be equal to what we have in testdata1/smaps_short
402     // Check for names
403     EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
404     EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
405     EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
406                 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
407             << "Unknown map name " << vmas[2].name;
408     EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
409     EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
410 
411     // Check start address
412     EXPECT_EQ(vmas[0].start, 0x54c00000);
413     EXPECT_EQ(vmas[1].start, 0x701ea000);
414     EXPECT_EQ(vmas[2].start, 0x70074dd8d000);
415     EXPECT_EQ(vmas[3].start, 0x700755a2d000);
416     EXPECT_EQ(vmas[4].start, 0x7007f85b0000);
417 
418     // Check end address
419     EXPECT_EQ(vmas[0].end, 0x56c00000);
420     EXPECT_EQ(vmas[1].end, 0x70cdb000);
421     EXPECT_EQ(vmas[2].end, 0x70074ee0d000);
422     EXPECT_EQ(vmas[3].end, 0x700755a6e000);
423     EXPECT_EQ(vmas[4].end, 0x7007f8b9b000);
424 
425     // Check Flags
426     EXPECT_EQ(vmas[0].flags, PROT_READ | PROT_EXEC);
427     EXPECT_EQ(vmas[1].flags, PROT_READ | PROT_WRITE);
428     EXPECT_EQ(vmas[2].flags, PROT_READ | PROT_WRITE);
429     EXPECT_EQ(vmas[3].flags, PROT_READ | PROT_EXEC);
430     EXPECT_EQ(vmas[4].flags, PROT_READ | PROT_EXEC);
431 
432     // Check Shared
433     EXPECT_FALSE(vmas[0].is_shared);
434     EXPECT_FALSE(vmas[1].is_shared);
435     EXPECT_FALSE(vmas[2].is_shared);
436     EXPECT_FALSE(vmas[3].is_shared);
437     EXPECT_FALSE(vmas[4].is_shared);
438 
439     // Check Offset
440     EXPECT_EQ(vmas[0].offset, 0x0);
441     EXPECT_EQ(vmas[1].offset, 0x0);
442     EXPECT_EQ(vmas[2].offset, 0x0);
443     EXPECT_EQ(vmas[3].offset, 0x00016000);
444     EXPECT_EQ(vmas[4].offset, 0x001ee000);
445 
446     // Check Inode
447     EXPECT_EQ(vmas[0].inode, 0);
448     EXPECT_EQ(vmas[1].inode, 3165);
449     EXPECT_EQ(vmas[2].inode, 0);
450     EXPECT_EQ(vmas[3].inode, 1947);
451     EXPECT_EQ(vmas[4].inode, 1537);
452 
453     // Check smaps specific fields
454     ASSERT_EQ(vmas[0].usage.vss, 32768);
455     EXPECT_EQ(vmas[1].usage.vss, 11204);
456     EXPECT_EQ(vmas[2].usage.vss, 16896);
457     EXPECT_EQ(vmas[3].usage.vss, 260);
458     EXPECT_EQ(vmas[4].usage.vss, 6060);
459 
460     EXPECT_EQ(vmas[0].usage.rss, 2048);
461     EXPECT_EQ(vmas[1].usage.rss, 11188);
462     EXPECT_EQ(vmas[2].usage.rss, 15272);
463     EXPECT_EQ(vmas[3].usage.rss, 260);
464     EXPECT_EQ(vmas[4].usage.rss, 4132);
465 
466     EXPECT_EQ(vmas[0].usage.pss, 113);
467     EXPECT_EQ(vmas[1].usage.pss, 2200);
468     EXPECT_EQ(vmas[2].usage.pss, 15272);
469     EXPECT_EQ(vmas[3].usage.pss, 260);
470     EXPECT_EQ(vmas[4].usage.pss, 1274);
471 
472     EXPECT_EQ(vmas[0].usage.uss, 0);
473     EXPECT_EQ(vmas[1].usage.uss, 1660);
474     EXPECT_EQ(vmas[2].usage.uss, 15272);
475     EXPECT_EQ(vmas[3].usage.uss, 260);
476     EXPECT_EQ(vmas[4].usage.uss, 0);
477 
478     EXPECT_EQ(vmas[0].usage.private_clean, 0);
479     EXPECT_EQ(vmas[1].usage.private_clean, 0);
480     EXPECT_EQ(vmas[2].usage.private_clean, 0);
481     EXPECT_EQ(vmas[3].usage.private_clean, 260);
482     EXPECT_EQ(vmas[4].usage.private_clean, 0);
483 
484     EXPECT_EQ(vmas[0].usage.private_dirty, 0);
485     EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
486     EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
487     EXPECT_EQ(vmas[3].usage.private_dirty, 0);
488     EXPECT_EQ(vmas[4].usage.private_dirty, 0);
489 
490     EXPECT_EQ(vmas[0].usage.shared_clean, 0);
491     EXPECT_EQ(vmas[1].usage.shared_clean, 80);
492     EXPECT_EQ(vmas[2].usage.shared_clean, 0);
493     EXPECT_EQ(vmas[3].usage.shared_clean, 0);
494     EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
495 
496     EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
497     EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
498     EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
499     EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
500     EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
501 
502     EXPECT_EQ(vmas[0].usage.swap, 0);
503     EXPECT_EQ(vmas[1].usage.swap, 0);
504     EXPECT_EQ(vmas[2].usage.swap, 0);
505     EXPECT_EQ(vmas[3].usage.swap, 0);
506     EXPECT_EQ(vmas[4].usage.swap, 0);
507 
508     EXPECT_EQ(vmas[0].usage.swap_pss, 0);
509     EXPECT_EQ(vmas[1].usage.swap_pss, 0);
510     EXPECT_EQ(vmas[2].usage.swap_pss, 0);
511     EXPECT_EQ(vmas[3].usage.swap_pss, 0);
512     EXPECT_EQ(vmas[4].usage.swap_pss, 0);
513 
514 #ifndef __x86_64__
515     // vmas[5] will not exist on x86, as [vsyscall] would not be processed.
516     EXPECT_EQ(vmas[5].name, "[vsyscall]");
517     EXPECT_EQ(vmas[5].start, 0xffffffffff600000);
518     EXPECT_EQ(vmas[5].end, 0xffffffffff601000);
519     EXPECT_EQ(vmas[5].flags, PROT_READ | PROT_EXEC);
520     EXPECT_FALSE(vmas[5].is_shared);
521     EXPECT_EQ(vmas[5].offset, 0x0);
522     EXPECT_EQ(vmas[5].inode, 0);
523     EXPECT_EQ(vmas[5].usage.vss, 4);
524     EXPECT_EQ(vmas[5].usage.rss, 0);
525     EXPECT_EQ(vmas[5].usage.pss, 0);
526     EXPECT_EQ(vmas[5].usage.uss, 0);
527     EXPECT_EQ(vmas[5].usage.private_clean, 0);
528     EXPECT_EQ(vmas[5].usage.private_dirty, 0);
529     EXPECT_EQ(vmas[5].usage.shared_clean, 0);
530     EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
531     EXPECT_EQ(vmas[5].usage.swap, 0);
532     EXPECT_EQ(vmas[5].usage.swap_pss, 0);
533 #endif
534 }
535 
TEST(ProcMemInfo,ForEachVmaFromFile_SmapsTest)536 TEST(ProcMemInfo, ForEachVmaFromFile_SmapsTest) {
537     // Parse smaps file correctly to make callbacks for each virtual memory area (vma)
538     std::string exec_dir = ::android::base::GetExecutableDirectory();
539     std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
540     ProcMemInfo proc_mem(pid);
541 
542     std::vector<Vma> vmas;
543     auto collect_vmas = [&](const Vma& v) {
544         vmas.push_back(v);
545         return true;
546     };
547     ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas));
548 
549     // We should get a total of 6 vmas
550     ASSERT_EQ(vmas.size(), 6);
551 
552     // Expect values to be equal to what we have in testdata1/smaps_short
553     // Check for names
554     EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
555     EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
556     EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
557                 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
558             << "Unknown map name " << vmas[2].name;
559     EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
560     EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
561     EXPECT_EQ(vmas[5].name, "[vsyscall]");
562 
563     // Check start address
564     EXPECT_EQ(vmas[0].start, 0x54c00000);
565     EXPECT_EQ(vmas[1].start, 0x701ea000);
566     EXPECT_EQ(vmas[2].start, 0x70074dd8d000);
567     EXPECT_EQ(vmas[3].start, 0x700755a2d000);
568     EXPECT_EQ(vmas[4].start, 0x7007f85b0000);
569     EXPECT_EQ(vmas[5].start, 0xffffffffff600000);
570 
571     // Check end address
572     EXPECT_EQ(vmas[0].end, 0x56c00000);
573     EXPECT_EQ(vmas[1].end, 0x70cdb000);
574     EXPECT_EQ(vmas[2].end, 0x70074ee0d000);
575     EXPECT_EQ(vmas[3].end, 0x700755a6e000);
576     EXPECT_EQ(vmas[4].end, 0x7007f8b9b000);
577     EXPECT_EQ(vmas[5].end, 0xffffffffff601000);
578 
579     // Check Flags
580     EXPECT_EQ(vmas[0].flags, PROT_READ | PROT_EXEC);
581     EXPECT_EQ(vmas[1].flags, PROT_READ | PROT_WRITE);
582     EXPECT_EQ(vmas[2].flags, PROT_READ | PROT_WRITE);
583     EXPECT_EQ(vmas[3].flags, PROT_READ | PROT_EXEC);
584     EXPECT_EQ(vmas[4].flags, PROT_READ | PROT_EXEC);
585     EXPECT_EQ(vmas[5].flags, PROT_READ | PROT_EXEC);
586 
587     // Check Shared
588     EXPECT_FALSE(vmas[0].is_shared);
589     EXPECT_FALSE(vmas[1].is_shared);
590     EXPECT_FALSE(vmas[2].is_shared);
591     EXPECT_FALSE(vmas[3].is_shared);
592     EXPECT_FALSE(vmas[4].is_shared);
593     EXPECT_FALSE(vmas[5].is_shared);
594 
595     // Check Offset
596     EXPECT_EQ(vmas[0].offset, 0x0);
597     EXPECT_EQ(vmas[1].offset, 0x0);
598     EXPECT_EQ(vmas[2].offset, 0x0);
599     EXPECT_EQ(vmas[3].offset, 0x00016000);
600     EXPECT_EQ(vmas[4].offset, 0x001ee000);
601     EXPECT_EQ(vmas[5].offset, 0x0);
602 
603     // Check Inode
604     EXPECT_EQ(vmas[0].inode, 0);
605     EXPECT_EQ(vmas[1].inode, 3165);
606     EXPECT_EQ(vmas[2].inode, 0);
607     EXPECT_EQ(vmas[3].inode, 1947);
608     EXPECT_EQ(vmas[4].inode, 1537);
609     EXPECT_EQ(vmas[5].inode, 0);
610 
611     // Check smaps specific fields
612     ASSERT_EQ(vmas[0].usage.vss, 32768);
613     EXPECT_EQ(vmas[1].usage.vss, 11204);
614     EXPECT_EQ(vmas[2].usage.vss, 16896);
615     EXPECT_EQ(vmas[3].usage.vss, 260);
616     EXPECT_EQ(vmas[4].usage.vss, 6060);
617     EXPECT_EQ(vmas[5].usage.vss, 4);
618 
619     EXPECT_EQ(vmas[0].usage.rss, 2048);
620     EXPECT_EQ(vmas[1].usage.rss, 11188);
621     EXPECT_EQ(vmas[2].usage.rss, 15272);
622     EXPECT_EQ(vmas[3].usage.rss, 260);
623     EXPECT_EQ(vmas[4].usage.rss, 4132);
624     EXPECT_EQ(vmas[5].usage.rss, 0);
625 
626     EXPECT_EQ(vmas[0].usage.pss, 113);
627     EXPECT_EQ(vmas[1].usage.pss, 2200);
628     EXPECT_EQ(vmas[2].usage.pss, 15272);
629     EXPECT_EQ(vmas[3].usage.pss, 260);
630     EXPECT_EQ(vmas[4].usage.pss, 1274);
631     EXPECT_EQ(vmas[5].usage.pss, 0);
632 
633     EXPECT_EQ(vmas[0].usage.uss, 0);
634     EXPECT_EQ(vmas[1].usage.uss, 1660);
635     EXPECT_EQ(vmas[2].usage.uss, 15272);
636     EXPECT_EQ(vmas[3].usage.uss, 260);
637     EXPECT_EQ(vmas[4].usage.uss, 0);
638     EXPECT_EQ(vmas[5].usage.uss, 0);
639 
640     EXPECT_EQ(vmas[0].usage.private_clean, 0);
641     EXPECT_EQ(vmas[1].usage.private_clean, 0);
642     EXPECT_EQ(vmas[2].usage.private_clean, 0);
643     EXPECT_EQ(vmas[3].usage.private_clean, 260);
644     EXPECT_EQ(vmas[4].usage.private_clean, 0);
645     EXPECT_EQ(vmas[5].usage.private_clean, 0);
646 
647     EXPECT_EQ(vmas[0].usage.private_dirty, 0);
648     EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
649     EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
650     EXPECT_EQ(vmas[3].usage.private_dirty, 0);
651     EXPECT_EQ(vmas[4].usage.private_dirty, 0);
652     EXPECT_EQ(vmas[5].usage.private_dirty, 0);
653 
654     EXPECT_EQ(vmas[0].usage.shared_clean, 0);
655     EXPECT_EQ(vmas[1].usage.shared_clean, 80);
656     EXPECT_EQ(vmas[2].usage.shared_clean, 0);
657     EXPECT_EQ(vmas[3].usage.shared_clean, 0);
658     EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
659     EXPECT_EQ(vmas[5].usage.shared_clean, 0);
660 
661     EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
662     EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
663     EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
664     EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
665     EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
666     EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
667 
668     EXPECT_EQ(vmas[0].usage.swap, 0);
669     EXPECT_EQ(vmas[1].usage.swap, 0);
670     EXPECT_EQ(vmas[2].usage.swap, 0);
671     EXPECT_EQ(vmas[3].usage.swap, 0);
672     EXPECT_EQ(vmas[4].usage.swap, 0);
673     EXPECT_EQ(vmas[5].usage.swap, 0);
674 
675     EXPECT_EQ(vmas[0].usage.swap_pss, 0);
676     EXPECT_EQ(vmas[1].usage.swap_pss, 0);
677     EXPECT_EQ(vmas[2].usage.swap_pss, 0);
678     EXPECT_EQ(vmas[3].usage.swap_pss, 0);
679     EXPECT_EQ(vmas[4].usage.swap_pss, 0);
680     EXPECT_EQ(vmas[5].usage.swap_pss, 0);
681 }
682 
TEST(ProcMemInfo,ForEachVmaFromFile_MapsTest)683 TEST(ProcMemInfo, ForEachVmaFromFile_MapsTest) {
684     // Parse maps file correctly to make callbacks for each virtual memory area (vma)
685     std::string exec_dir = ::android::base::GetExecutableDirectory();
686     std::string path = ::android::base::StringPrintf("%s/testdata1/maps_short", exec_dir.c_str());
687     ProcMemInfo proc_mem(pid);
688 
689     std::vector<Vma> vmas;
690     auto collect_vmas = [&](const Vma& v) {
691         vmas.push_back(v);
692         return true;
693     };
694     ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas, false));
695 
696     // We should get a total of 6 vmas
697     ASSERT_EQ(vmas.size(), 6);
698 
699     // Expect values to be equal to what we have in testdata1/maps_short
700     // Check for names
701     EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
702     EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
703     EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
704                 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
705             << "Unknown map name " << vmas[2].name;
706     EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
707     EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
708     EXPECT_EQ(vmas[5].name, "[vsyscall]");
709 
710     // Check start address
711     EXPECT_EQ(vmas[0].start, 0x54c00000);
712     EXPECT_EQ(vmas[1].start, 0x701ea000);
713     EXPECT_EQ(vmas[2].start, 0x70074dd8d000);
714     EXPECT_EQ(vmas[3].start, 0x700755a2d000);
715     EXPECT_EQ(vmas[4].start, 0x7007f85b0000);
716     EXPECT_EQ(vmas[5].start, 0xffffffffff600000);
717 
718     // Check end address
719     EXPECT_EQ(vmas[0].end, 0x56c00000);
720     EXPECT_EQ(vmas[1].end, 0x70cdb000);
721     EXPECT_EQ(vmas[2].end, 0x70074ee0d000);
722     EXPECT_EQ(vmas[3].end, 0x700755a6e000);
723     EXPECT_EQ(vmas[4].end, 0x7007f8b9b000);
724     EXPECT_EQ(vmas[5].end, 0xffffffffff601000);
725 
726     // Check Flags
727     EXPECT_EQ(vmas[0].flags, PROT_READ | PROT_EXEC);
728     EXPECT_EQ(vmas[1].flags, PROT_READ | PROT_WRITE);
729     EXPECT_EQ(vmas[2].flags, PROT_READ | PROT_WRITE);
730     EXPECT_EQ(vmas[3].flags, PROT_READ | PROT_EXEC);
731     EXPECT_EQ(vmas[4].flags, PROT_READ | PROT_EXEC);
732     EXPECT_EQ(vmas[5].flags, PROT_READ | PROT_EXEC);
733 
734     // Check Shared
735     EXPECT_FALSE(vmas[0].is_shared);
736     EXPECT_FALSE(vmas[1].is_shared);
737     EXPECT_FALSE(vmas[2].is_shared);
738     EXPECT_FALSE(vmas[3].is_shared);
739     EXPECT_FALSE(vmas[4].is_shared);
740     EXPECT_FALSE(vmas[5].is_shared);
741 
742     // Check Offset
743     EXPECT_EQ(vmas[0].offset, 0x0);
744     EXPECT_EQ(vmas[1].offset, 0x0);
745     EXPECT_EQ(vmas[2].offset, 0x0);
746     EXPECT_EQ(vmas[3].offset, 0x00016000);
747     EXPECT_EQ(vmas[4].offset, 0x001ee000);
748     EXPECT_EQ(vmas[5].offset, 0x0);
749 
750     // Check Inode
751     EXPECT_EQ(vmas[0].inode, 0);
752     EXPECT_EQ(vmas[1].inode, 3165);
753     EXPECT_EQ(vmas[2].inode, 0);
754     EXPECT_EQ(vmas[3].inode, 1947);
755     EXPECT_EQ(vmas[4].inode, 1537);
756     EXPECT_EQ(vmas[5].inode, 0);
757 }
758 
TEST(ProcMemInfo,SmapsReturnTest)759 TEST(ProcMemInfo, SmapsReturnTest) {
760     // Make sure Smaps() is never empty for any process
761     ProcMemInfo proc_mem(pid);
762     auto vmas = proc_mem.Smaps();
763     EXPECT_FALSE(vmas.empty());
764 }
765 
TEST(ProcMemInfo,SmapsTest)766 TEST(ProcMemInfo, SmapsTest) {
767     std::string exec_dir = ::android::base::GetExecutableDirectory();
768     std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
769     ProcMemInfo proc_mem(pid);
770     auto vmas = proc_mem.Smaps(path);
771 
772     ASSERT_FALSE(vmas.empty());
773 #ifndef __x86_64__
774     // We should get a total of 6 vmas
775     ASSERT_EQ(vmas.size(), 6);
776 #else
777     // We should get a total of 5 vmas ([vsyscall] is excluded)
778     ASSERT_EQ(vmas.size(), 5);
779 #endif
780 
781     // Expect values to be equal to what we have in testdata1/smaps_short
782     // Check for sizes first
783     ASSERT_EQ(vmas[0].usage.vss, 32768);
784     EXPECT_EQ(vmas[1].usage.vss, 11204);
785     EXPECT_EQ(vmas[2].usage.vss, 16896);
786     EXPECT_EQ(vmas[3].usage.vss, 260);
787     EXPECT_EQ(vmas[4].usage.vss, 6060);
788 #ifndef __x86_64__
789     EXPECT_EQ(vmas[5].usage.vss, 4);
790 #endif
791 
792     // Check for names
793     EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
794     EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
795     EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
796                 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
797             << "Unknown map name " << vmas[2].name;
798     EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
799     EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
800 #ifndef __x86_64__
801     EXPECT_EQ(vmas[5].name, "[vsyscall]");
802 #endif
803 
804     EXPECT_EQ(vmas[0].usage.rss, 2048);
805     EXPECT_EQ(vmas[1].usage.rss, 11188);
806     EXPECT_EQ(vmas[2].usage.rss, 15272);
807     EXPECT_EQ(vmas[3].usage.rss, 260);
808     EXPECT_EQ(vmas[4].usage.rss, 4132);
809 #ifndef __x86_64__
810     EXPECT_EQ(vmas[5].usage.rss, 0);
811 #endif
812 
813     EXPECT_EQ(vmas[0].usage.pss, 113);
814     EXPECT_EQ(vmas[1].usage.pss, 2200);
815     EXPECT_EQ(vmas[2].usage.pss, 15272);
816     EXPECT_EQ(vmas[3].usage.pss, 260);
817     EXPECT_EQ(vmas[4].usage.pss, 1274);
818 #ifndef __x86_64__
819     EXPECT_EQ(vmas[5].usage.pss, 0);
820 #endif
821 
822     EXPECT_EQ(vmas[0].usage.uss, 0);
823     EXPECT_EQ(vmas[1].usage.uss, 1660);
824     EXPECT_EQ(vmas[2].usage.uss, 15272);
825     EXPECT_EQ(vmas[3].usage.uss, 260);
826     EXPECT_EQ(vmas[4].usage.uss, 0);
827 #ifndef __x86_64__
828     EXPECT_EQ(vmas[5].usage.uss, 0);
829 #endif
830 
831     EXPECT_EQ(vmas[0].usage.private_clean, 0);
832     EXPECT_EQ(vmas[1].usage.private_clean, 0);
833     EXPECT_EQ(vmas[2].usage.private_clean, 0);
834     EXPECT_EQ(vmas[3].usage.private_clean, 260);
835     EXPECT_EQ(vmas[4].usage.private_clean, 0);
836 #ifndef __x86_64__
837     EXPECT_EQ(vmas[5].usage.private_clean, 0);
838 #endif
839 
840     EXPECT_EQ(vmas[0].usage.private_dirty, 0);
841     EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
842     EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
843     EXPECT_EQ(vmas[3].usage.private_dirty, 0);
844     EXPECT_EQ(vmas[4].usage.private_dirty, 0);
845 #ifndef __x86_64__
846     EXPECT_EQ(vmas[5].usage.private_dirty, 0);
847 #endif
848 
849     EXPECT_EQ(vmas[0].usage.shared_clean, 0);
850     EXPECT_EQ(vmas[1].usage.shared_clean, 80);
851     EXPECT_EQ(vmas[2].usage.shared_clean, 0);
852     EXPECT_EQ(vmas[3].usage.shared_clean, 0);
853     EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
854 #ifndef __x86_64__
855     EXPECT_EQ(vmas[5].usage.shared_clean, 0);
856 #endif
857 
858     EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
859     EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
860     EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
861     EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
862     EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
863 #ifndef __x86_64__
864     EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
865 #endif
866 
867     EXPECT_EQ(vmas[0].usage.swap, 0);
868     EXPECT_EQ(vmas[1].usage.swap, 0);
869     EXPECT_EQ(vmas[2].usage.swap, 0);
870     EXPECT_EQ(vmas[3].usage.swap, 0);
871     EXPECT_EQ(vmas[4].usage.swap, 0);
872 #ifndef __x86_64__
873     EXPECT_EQ(vmas[5].usage.swap, 0);
874 #endif
875 
876     EXPECT_EQ(vmas[0].usage.swap_pss, 0);
877     EXPECT_EQ(vmas[1].usage.swap_pss, 0);
878     EXPECT_EQ(vmas[2].usage.swap_pss, 0);
879     EXPECT_EQ(vmas[3].usage.swap_pss, 0);
880     EXPECT_EQ(vmas[4].usage.swap_pss, 0);
881 #ifndef __x86_64__
882     EXPECT_EQ(vmas[5].usage.swap_pss, 0);
883 #endif
884 }
885 
TEST(ProcMemInfo,SmapsPopulatesUsageTest)886 TEST(ProcMemInfo, SmapsPopulatesUsageTest) {
887     std::string exec_dir = ::android::base::GetExecutableDirectory();
888     std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
889     ProcMemInfo proc_mem(pid);
890     auto vmas = proc_mem.Smaps(path, true);
891 
892     // Expect values to be equal to sums of usage in testdata1/smaps_short. For
893     // this data, only vss differs on x86.
894 #ifndef __x86_64__
895     EXPECT_EQ(proc_mem.Usage().vss, 67192);
896 #else
897     EXPECT_EQ(proc_mem.Usage().vss, 67188);
898 #endif
899     EXPECT_EQ(proc_mem.Usage().rss, 32900);
900     EXPECT_EQ(proc_mem.Usage().pss, 19119);
901     EXPECT_EQ(proc_mem.Usage().uss, 17192);
902     EXPECT_EQ(proc_mem.Usage().private_clean, 260);
903     EXPECT_EQ(proc_mem.Usage().private_dirty, 16932);
904     EXPECT_EQ(proc_mem.Usage().shared_clean, 4212);
905     EXPECT_EQ(proc_mem.Usage().shared_dirty, 11496);
906     EXPECT_EQ(proc_mem.Usage().swap, 0);
907     EXPECT_EQ(proc_mem.Usage().swap_pss, 0);
908 }
909 
TEST(SysMemInfo,TestSysMemInfoFile)910 TEST(SysMemInfo, TestSysMemInfoFile) {
911     std::string meminfo = R"meminfo(MemTotal:        3019740 kB
912 MemFree:         1809728 kB
913 MemAvailable:    2546560 kB
914 Buffers:           54736 kB
915 Cached:           776052 kB
916 SwapCached:            0 kB
917 Active:           445856 kB
918 Inactive:         459092 kB
919 Active(anon):      78492 kB
920 Inactive(anon):     2240 kB
921 Active(file):     367364 kB
922 Inactive(file):   456852 kB
923 Unevictable:        3096 kB
924 Mlocked:            3096 kB
925 SwapTotal:         32768 kB
926 SwapFree:           4096 kB
927 Dirty:                32 kB
928 Writeback:             0 kB
929 AnonPages:         74988 kB
930 Mapped:            62624 kB
931 Shmem:              4020 kB
932 KReclaimable:      87324 kB
933 Slab:              86464 kB
934 SReclaimable:      44432 kB
935 SUnreclaim:        42032 kB
936 KernelStack:        4880 kB
937 PageTables:         2900 kB
938 NFS_Unstable:          0 kB
939 Bounce:                0 kB
940 WritebackTmp:          0 kB
941 CommitLimit:     1509868 kB
942 Committed_AS:      80296 kB
943 VmallocTotal:   263061440 kB
944 VmallocUsed:       65536 kB
945 VmallocChunk:          0 kB
946 AnonHugePages:      6144 kB
947 ShmemHugePages:        0 kB
948 ShmemPmdMapped:        0 kB
949 CmaTotal:         131072 kB
950 CmaFree:          130380 kB
951 HugePages_Total:       0
952 HugePages_Free:        0
953 HugePages_Rsvd:        0
954 HugePages_Surp:        0
955 Hugepagesize:       2048 kB)meminfo";
956 
957     TemporaryFile tf;
958     ASSERT_TRUE(tf.fd != -1);
959     ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
960 
961     SysMemInfo mi;
962     ASSERT_TRUE(mi.ReadMemInfo(tf.path));
963     EXPECT_EQ(mi.mem_total_kb(), 3019740);
964     EXPECT_EQ(mi.mem_free_kb(), 1809728);
965     EXPECT_EQ(mi.mem_buffers_kb(), 54736);
966     EXPECT_EQ(mi.mem_cached_kb(), 776052);
967     EXPECT_EQ(mi.mem_shmem_kb(), 4020);
968     EXPECT_EQ(mi.mem_slab_kb(), 86464);
969     EXPECT_EQ(mi.mem_slab_reclaimable_kb(), 44432);
970     EXPECT_EQ(mi.mem_slab_unreclaimable_kb(), 42032);
971     EXPECT_EQ(mi.mem_swap_kb(), 32768);
972     EXPECT_EQ(mi.mem_swap_free_kb(), 4096);
973     EXPECT_EQ(mi.mem_mapped_kb(), 62624);
974     EXPECT_EQ(mi.mem_vmalloc_used_kb(), 65536);
975     EXPECT_EQ(mi.mem_page_tables_kb(), 2900);
976     EXPECT_EQ(mi.mem_kernel_stack_kb(), 4880);
977     EXPECT_EQ(mi.mem_kreclaimable_kb(), 87324);
978     EXPECT_EQ(mi.mem_active_kb(), 445856);
979     EXPECT_EQ(mi.mem_inactive_kb(), 459092);
980     EXPECT_EQ(mi.mem_unevictable_kb(), 3096);
981     EXPECT_EQ(mi.mem_available_kb(), 2546560);
982     EXPECT_EQ(mi.mem_active_anon_kb(), 78492);
983     EXPECT_EQ(mi.mem_inactive_anon_kb(), 2240);
984     EXPECT_EQ(mi.mem_active_file_kb(), 367364);
985     EXPECT_EQ(mi.mem_inactive_file_kb(), 456852);
986     EXPECT_EQ(mi.mem_cma_total_kb(), 131072);
987     EXPECT_EQ(mi.mem_cma_free_kb(), 130380);
988 }
989 
TEST(SysMemInfo,TestEmptyFile)990 TEST(SysMemInfo, TestEmptyFile) {
991     TemporaryFile tf;
992     std::string empty_string = "";
993     ASSERT_TRUE(tf.fd != -1);
994     ASSERT_TRUE(::android::base::WriteStringToFd(empty_string, tf.fd));
995 
996     SysMemInfo mi;
997     EXPECT_TRUE(mi.ReadMemInfo(tf.path));
998     EXPECT_EQ(mi.mem_total_kb(), 0);
999 }
1000 
TEST(SysMemInfo,TestZramTotal)1001 TEST(SysMemInfo, TestZramTotal) {
1002     std::string exec_dir = ::android::base::GetExecutableDirectory();
1003 
1004     SysMemInfo mi;
1005     std::string zram_mmstat_dir = exec_dir + "/testdata1/";
1006     EXPECT_EQ(mi.mem_zram_kb(zram_mmstat_dir.c_str()), 30504);
1007 
1008     std::string zram_memused_dir = exec_dir + "/testdata2/";
1009     EXPECT_EQ(mi.mem_zram_kb(zram_memused_dir.c_str()), 30504);
1010 }
1011 
1012 enum {
1013     MEMINFO_TOTAL,
1014     MEMINFO_FREE,
1015     MEMINFO_BUFFERS,
1016     MEMINFO_CACHED,
1017     MEMINFO_SHMEM,
1018     MEMINFO_SLAB,
1019     MEMINFO_SLAB_RECLAIMABLE,
1020     MEMINFO_SLAB_UNRECLAIMABLE,
1021     MEMINFO_SWAP_TOTAL,
1022     MEMINFO_SWAP_FREE,
1023     MEMINFO_ZRAM_TOTAL,
1024     MEMINFO_MAPPED,
1025     MEMINFO_VMALLOC_USED,
1026     MEMINFO_PAGE_TABLES,
1027     MEMINFO_KERNEL_STACK,
1028     MEMINFO_KRECLAIMABLE,
1029     MEMINFO_ACTIVE,
1030     MEMINFO_INACTIVE,
1031     MEMINFO_UNEVICTABLE,
1032     MEMINFO_AVAILABLE,
1033     MEMINFO_ACTIVE_ANON,
1034     MEMINFO_INACTIVE_ANON,
1035     MEMINFO_ACTIVE_FILE,
1036     MEMINFO_INACTIVE_FILE,
1037     MEMINFO_CMA_TOTAL,
1038     MEMINFO_CMA_FREE,
1039     MEMINFO_COUNT
1040 };
1041 
TEST(SysMemInfo,TestZramWithTags)1042 TEST(SysMemInfo, TestZramWithTags) {
1043     std::string meminfo = R"meminfo(MemTotal:        3019740 kB
1044 MemFree:         1809728 kB
1045 MemAvailable:    2546560 kB
1046 Buffers:           54736 kB
1047 Cached:           776052 kB
1048 SwapCached:            0 kB
1049 Active:           445856 kB
1050 Inactive:         459092 kB
1051 Active(anon):      78492 kB
1052 Inactive(anon):     2240 kB
1053 Active(file):     367364 kB
1054 Inactive(file):   456852 kB
1055 Unevictable:        3096 kB
1056 Mlocked:            3096 kB
1057 SwapTotal:         32768 kB
1058 SwapFree:           4096 kB
1059 Dirty:                32 kB
1060 Writeback:             0 kB
1061 AnonPages:         74988 kB
1062 Mapped:            62624 kB
1063 Shmem:              4020 kB
1064 KReclaimable:      87324 kB
1065 Slab:              86464 kB
1066 SReclaimable:      44432 kB
1067 SUnreclaim:        42032 kB
1068 KernelStack:        4880 kB
1069 PageTables:         2900 kB
1070 NFS_Unstable:          0 kB
1071 Bounce:                0 kB
1072 WritebackTmp:          0 kB
1073 CommitLimit:     1509868 kB
1074 Committed_AS:      80296 kB
1075 VmallocTotal:   263061440 kB
1076 VmallocUsed:       65536 kB
1077 VmallocChunk:          0 kB
1078 AnonHugePages:      6144 kB
1079 ShmemHugePages:        0 kB
1080 ShmemPmdMapped:        0 kB
1081 CmaTotal:         131072 kB
1082 CmaFree:          130380 kB
1083 HugePages_Total:       0
1084 HugePages_Free:        0
1085 HugePages_Rsvd:        0
1086 HugePages_Surp:        0
1087 Hugepagesize:       2048 kB)meminfo";
1088 
1089     TemporaryFile tf;
1090     ASSERT_TRUE(tf.fd != -1);
1091     ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
1092     std::string file = std::string(tf.path);
1093     std::vector<uint64_t> mem;
1094     std::vector<std::string_view> tags(SysMemInfo::kDefaultSysMemInfoTags.begin(),
1095                                        SysMemInfo::kDefaultSysMemInfoTags.end());
1096     auto it = tags.begin();
1097     tags.insert(it + MEMINFO_ZRAM_TOTAL, "Zram:");
1098     SysMemInfo mi;
1099 
1100     // Read system memory info
1101     mem.resize(tags.size());
1102     EXPECT_TRUE(mi.ReadMemInfo(tags.size(), tags.data(), mem.data(), file.c_str()));
1103     EXPECT_EQ(mem[MEMINFO_TOTAL], 3019740);
1104     EXPECT_EQ(mem[MEMINFO_FREE], 1809728);
1105     EXPECT_EQ(mem[MEMINFO_BUFFERS], 54736);
1106     EXPECT_EQ(mem[MEMINFO_CACHED], 776052);
1107     EXPECT_EQ(mem[MEMINFO_SHMEM], 4020);
1108     EXPECT_EQ(mem[MEMINFO_SLAB], 86464);
1109     EXPECT_EQ(mem[MEMINFO_SLAB_RECLAIMABLE], 44432);
1110     EXPECT_EQ(mem[MEMINFO_SLAB_UNRECLAIMABLE], 42032);
1111     EXPECT_EQ(mem[MEMINFO_SWAP_TOTAL], 32768);
1112     EXPECT_EQ(mem[MEMINFO_SWAP_FREE], 4096);
1113     EXPECT_EQ(mem[MEMINFO_MAPPED], 62624);
1114     EXPECT_EQ(mem[MEMINFO_VMALLOC_USED], 65536);
1115     EXPECT_EQ(mem[MEMINFO_PAGE_TABLES], 2900);
1116     EXPECT_EQ(mem[MEMINFO_KERNEL_STACK], 4880);
1117     EXPECT_EQ(mem[MEMINFO_KRECLAIMABLE], 87324);
1118     EXPECT_EQ(mem[MEMINFO_ACTIVE], 445856);
1119     EXPECT_EQ(mem[MEMINFO_INACTIVE], 459092);
1120     EXPECT_EQ(mem[MEMINFO_UNEVICTABLE], 3096);
1121     EXPECT_EQ(mem[MEMINFO_AVAILABLE], 2546560);
1122     EXPECT_EQ(mem[MEMINFO_ACTIVE_ANON], 78492);
1123     EXPECT_EQ(mem[MEMINFO_INACTIVE_ANON], 2240);
1124     EXPECT_EQ(mem[MEMINFO_ACTIVE_FILE], 367364);
1125     EXPECT_EQ(mem[MEMINFO_INACTIVE_FILE], 456852);
1126     EXPECT_EQ(mem[MEMINFO_CMA_TOTAL], 131072);
1127     EXPECT_EQ(mem[MEMINFO_CMA_FREE], 130380);
1128 }
1129 
TEST(SysMemInfo,TestVmallocInfoNoMemory)1130 TEST(SysMemInfo, TestVmallocInfoNoMemory) {
1131     std::string vmallocinfo =
1132             R"vmallocinfo(0x0000000000000000-0x0000000000000000   69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
1133 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
1134 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
1135 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap)vmallocinfo";
1136 
1137     TemporaryFile tf;
1138     ASSERT_TRUE(tf.fd != -1);
1139     ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
1140     std::string file = std::string(tf.path);
1141 
1142     EXPECT_EQ(ReadVmallocInfo(file.c_str()), 0);
1143 }
1144 
TEST(SysMemInfo,TestVmallocInfoKernel)1145 TEST(SysMemInfo, TestVmallocInfoKernel) {
1146     std::string vmallocinfo =
1147             R"vmallocinfo(0x0000000000000000-0x0000000000000000    8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc)vmallocinfo";
1148 
1149     TemporaryFile tf;
1150     ASSERT_TRUE(tf.fd != -1);
1151     ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
1152     std::string file = std::string(tf.path);
1153 
1154     EXPECT_EQ(ReadVmallocInfo(file.c_str()), getpagesize());
1155 }
1156 
TEST(SysMemInfo,TestVmallocInfoModule)1157 TEST(SysMemInfo, TestVmallocInfoModule) {
1158     std::string vmallocinfo =
1159             R"vmallocinfo(0x0000000000000000-0x0000000000000000   28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
1160 
1161     TemporaryFile tf;
1162     ASSERT_TRUE(tf.fd != -1);
1163     ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
1164     std::string file = std::string(tf.path);
1165 
1166     EXPECT_EQ(ReadVmallocInfo(file.c_str()), 6 * getpagesize());
1167 }
1168 
TEST(SysMemInfo,TestVmallocInfoAll)1169 TEST(SysMemInfo, TestVmallocInfoAll) {
1170     std::string vmallocinfo =
1171             R"vmallocinfo(0x0000000000000000-0x0000000000000000   69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
1172 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
1173 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
1174 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap
1175 0x0000000000000000-0x0000000000000000    8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc
1176 0x0000000000000000-0x0000000000000000   28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
1177 
1178     TemporaryFile tf;
1179     ASSERT_TRUE(tf.fd != -1);
1180     ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
1181     std::string file = std::string(tf.path);
1182 
1183     EXPECT_EQ(ReadVmallocInfo(file.c_str()), 7 * getpagesize());
1184 }
1185 
TEST(SysMemInfo,TestReadIonHeapsSizeKb)1186 TEST(SysMemInfo, TestReadIonHeapsSizeKb) {
1187     std::string total_heaps_kb = R"total_heaps_kb(98480)total_heaps_kb";
1188     uint64_t size;
1189 
1190     TemporaryFile tf;
1191     ASSERT_TRUE(tf.fd != -1);
1192     ASSERT_TRUE(::android::base::WriteStringToFd(total_heaps_kb, tf.fd));
1193     std::string file = std::string(tf.path);
1194 
1195     ASSERT_TRUE(ReadIonHeapsSizeKb(&size, file));
1196     EXPECT_EQ(size, 98480);
1197 }
1198 
TEST(SysMemInfo,TestReadIonPoolsSizeKb)1199 TEST(SysMemInfo, TestReadIonPoolsSizeKb) {
1200     std::string total_pools_kb = R"total_pools_kb(416)total_pools_kb";
1201     uint64_t size;
1202 
1203     TemporaryFile tf;
1204     ASSERT_TRUE(tf.fd != -1);
1205     ASSERT_TRUE(::android::base::WriteStringToFd(total_pools_kb, tf.fd));
1206     std::string file = std::string(tf.path);
1207 
1208     ASSERT_TRUE(ReadIonPoolsSizeKb(&size, file));
1209     EXPECT_EQ(size, 416);
1210 }
1211 
TEST(SysMemInfo,TestReadGpuTotalUsageKb)1212 TEST(SysMemInfo, TestReadGpuTotalUsageKb) {
1213     uint64_t size;
1214 
1215     if (android::base::GetIntProperty("ro.vendor.api_level", 0) < __ANDROID_API_S__) {
1216         GTEST_SKIP();
1217     }
1218 
1219     KernelVersion min_kernel_version = KernelVersion(5, 4, 0);
1220     KernelVersion kernel_version = VintfObject::GetInstance()
1221                                            ->getRuntimeInfo(RuntimeInfo::FetchFlag::CPU_VERSION)
1222                                            ->kernelVersion();
1223     if (kernel_version < min_kernel_version) {
1224         GTEST_SKIP();
1225     }
1226 
1227     ASSERT_TRUE(ReadGpuTotalUsageKb(&size));
1228     EXPECT_TRUE(size >= 0);
1229 }
1230 
TEST(AndroidProcHeaps,ExtractAndroidHeapStatsFromFileTest)1231 TEST(AndroidProcHeaps, ExtractAndroidHeapStatsFromFileTest) {
1232     std::string smaps =
1233             R"smaps(12c00000-13440000 rw-p 00000000 00:00 0  [anon:dalvik-main space (region space)]
1234 Name:           [anon:dalvik-main space (region space)]
1235 Size:               8448 kB
1236 KernelPageSize:        4 kB
1237 MMUPageSize:           4 kB
1238 Rss:                2652 kB
1239 Pss:                2652 kB
1240 Shared_Clean:        840 kB
1241 Shared_Dirty:         40 kB
1242 Private_Clean:        84 kB
1243 Private_Dirty:      2652 kB
1244 Referenced:         2652 kB
1245 Anonymous:          2652 kB
1246 AnonHugePages:         0 kB
1247 ShmemPmdMapped:        0 kB
1248 Shared_Hugetlb:        0 kB
1249 Private_Hugetlb:       0 kB
1250 Swap:                102 kB
1251 SwapPss:              70 kB
1252 Locked:             2652 kB
1253 VmFlags: rd wr mr mw me ac
1254 )smaps";
1255 
1256     TemporaryFile tf;
1257     ASSERT_TRUE(tf.fd != -1);
1258     ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
1259 
1260     bool foundSwapPss;
1261     AndroidHeapStats stats[_NUM_HEAP];
1262     ASSERT_TRUE(ExtractAndroidHeapStatsFromFile(tf.path, stats, &foundSwapPss));
1263 
1264     AndroidHeapStats actualStats;
1265     for (int i = 0; i < _NUM_CORE_HEAP; i++) {
1266         actualStats.pss += stats[i].pss;
1267         actualStats.swappablePss += stats[i].swappablePss;
1268         actualStats.rss += stats[i].rss;
1269         actualStats.privateDirty += stats[i].privateDirty;
1270         actualStats.sharedDirty += stats[i].sharedDirty;
1271         actualStats.privateClean += stats[i].privateClean;
1272         actualStats.sharedClean += stats[i].sharedClean;
1273         actualStats.swappedOut += stats[i].swappedOut;
1274         actualStats.swappedOutPss += stats[i].swappedOutPss;
1275     }
1276     EXPECT_EQ(actualStats.pss, 2652);
1277     EXPECT_EQ(actualStats.swappablePss, 0);
1278     EXPECT_EQ(actualStats.rss, 2652);
1279     EXPECT_EQ(actualStats.privateDirty, 2652);
1280     EXPECT_EQ(actualStats.sharedDirty, 40);
1281     EXPECT_EQ(actualStats.privateClean, 84);
1282     EXPECT_EQ(actualStats.sharedClean, 840);
1283     EXPECT_EQ(actualStats.swappedOut, 102);
1284     EXPECT_EQ(actualStats.swappedOutPss, 70);
1285 }
1286 
1287 class DmabufHeapStats : public ::testing::Test {
1288   public:
SetUp()1289     virtual void SetUp() {
1290         fs::current_path(fs::temp_directory_path());
1291         buffer_stats_path = fs::current_path() / "buffers";
1292         ASSERT_TRUE(fs::create_directory(buffer_stats_path));
1293         heap_root_path = fs::current_path() / "dma_heap";
1294         ASSERT_TRUE(fs::create_directory(heap_root_path));
1295     }
TearDown()1296     virtual void TearDown() {
1297         fs::remove_all(buffer_stats_path);
1298         fs::remove_all(heap_root_path);
1299     }
1300 
1301     fs::path buffer_stats_path;
1302     fs::path heap_root_path;
1303 };
1304 
TEST_F(DmabufHeapStats,TestDmabufHeapTotalExportedKb)1305 TEST_F(DmabufHeapStats, TestDmabufHeapTotalExportedKb) {
1306     using android::base::StringPrintf;
1307     uint64_t size;
1308 
1309     auto system_heap_path = heap_root_path / "system";
1310     ASSERT_TRUE(android::base::WriteStringToFile("test", system_heap_path));
1311 
1312     for (unsigned int inode_number = 74831; inode_number < 74841; inode_number++) {
1313         auto buffer_path = buffer_stats_path / StringPrintf("%u", inode_number);
1314         ASSERT_TRUE(fs::create_directories(buffer_path));
1315 
1316         auto buffer_size_path = buffer_path / "size";
1317         const std::string buffer_size = "4096";
1318         ASSERT_TRUE(android::base::WriteStringToFile(buffer_size, buffer_size_path));
1319 
1320         auto exp_name_path = buffer_path / "exporter_name";
1321         const std::string exp_name = inode_number % 2 ? "system" : "other";
1322         ASSERT_TRUE(android::base::WriteStringToFile(exp_name, exp_name_path));
1323     }
1324 
1325     ASSERT_TRUE(ReadDmabufHeapTotalExportedKb(&size, heap_root_path, buffer_stats_path));
1326     ASSERT_EQ(size, 20);
1327 }
1328 
TEST(SysMemInfo,TestReadDmaBufHeapPoolsSizeKb)1329 TEST(SysMemInfo, TestReadDmaBufHeapPoolsSizeKb) {
1330     std::string total_pools_kb = R"total_pools_kb(416)total_pools_kb";
1331     uint64_t size;
1332 
1333     TemporaryFile tf;
1334     ASSERT_TRUE(tf.fd != -1);
1335     ASSERT_TRUE(::android::base::WriteStringToFd(total_pools_kb, tf.fd));
1336     std::string file = std::string(tf.path);
1337 
1338     ASSERT_TRUE(ReadDmabufHeapPoolsSizeKb(&size, file));
1339     EXPECT_EQ(size, 416);
1340 }
1341 
main(int argc,char ** argv)1342 int main(int argc, char** argv) {
1343     ::testing::InitGoogleTest(&argc, argv);
1344     ::android::base::InitLogging(argv, android::base::StderrLogger);
1345     pid = getpid();
1346     return RUN_ALL_TESTS();
1347 }
1348