• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef SMAPS_STATS_H
17 #define SMAPS_STATS_H
18 
19 #include <array>
20 #include <cinttypes>
21 #include <cstdio>
22 #include <fstream>
23 #include <inttypes.h>
24 #include <iostream>
25 #include <memory>
26 #include <string>
27 #include <sys/mman.h>
28 #include "logging.h"
29 
30 struct MemUsageInfo {
31     uint64_t vss;
32     uint64_t rss;
33     uint64_t pss;
34     uint64_t uss;
35 
36     uint64_t swap;
37     uint64_t swapPss;
38 
39     uint64_t privateClean;
40     uint64_t privateDirty;
41     uint64_t sharedClean;
42     uint64_t sharedDirty;
43 };
44 
45 class StatsInfo {
46 public:
47     int pss_;
48     int swappablePss_;
49     int rss_;
50     int privateDirty_;
51     int sharedDirty_;
52     int privateClean_;
53     int sharedClean_;
54     int swappedOut_;
55     int swappedOutPss_;
56 
StatsInfo()57     StatsInfo()
58         : pss_(0),
59         swappablePss_(0),
60         rss_(0),
61         privateDirty_(0),
62         sharedDirty_(0),
63         privateClean_(0),
64         sharedClean_(0),
65         swappedOut_(0),
66         swappedOutPss_(0)
67     {
68     }
69 
StatsInfo(uint64_t swapablePss,const MemUsageInfo & usage)70     StatsInfo(uint64_t swapablePss, const MemUsageInfo& usage)
71         : pss_(usage.pss),
72         swappablePss_(swapablePss),
73         rss_(usage.rss),
74         privateDirty_(usage.privateDirty),
75         sharedDirty_(usage.sharedDirty),
76         privateClean_(usage.privateClean),
77         sharedClean_(usage.sharedClean),
78         swappedOut_(usage.swap),
79         swappedOutPss_(usage.swapPss)
80     {
81     }
~StatsInfo()82     ~StatsInfo() {}
83 
84     void operator+=(const StatsInfo &S)
85     {
86         pss_ += S.pss_;
87         swappablePss_ += S.swappablePss_;
88         rss_ += S.rss_;
89         privateDirty_ += S.privateDirty_;
90         sharedDirty_ += S.sharedDirty_;
91         privateClean_ += S.privateClean_;
92         sharedClean_ += S.sharedClean_;
93         swappedOut_ += S.swappedOut_;
94         swappedOutPss_ += S.swappedOutPss_;
95     }
96 };
97 
98 enum NumType {
99     FIFTH_FIELD = 5,
100     HEX_BASE = 16,
101     DEC_BASE = 10,
102 };
103 
104 struct MapPiecesInfo {
105     uint64_t startAddr;
106     uint64_t endAddr;
107 
108     std::string name;
109 };
110 
111 enum VmemifoType {
112     VMHEAP_NULL = -2,
113     VMHEAP_NEEDFIX = -1,
114     VMHEAP_UNKNOWN,
115     VMHEAP_SENSITIVE_VM,
116     VMHEAP_NATIVE,
117 
118     VMHEAP_SENSITIVE_VM_OTHER,
119     VMHEAP_STACK,
120     VMHEAP_CURSOR,
121     VMHEAP_ASHMEM,
122     VMHEAP_GL_DEV,
123     VMHEAP_UNKNOWN_DEV,
124     VMHEAP_SO,
125     VMHEAP_JAR,
126     VMHEAP_TTF,
127     VMHEAP_SENSITIVE_JVBIN,
128     VMHEAP_OAT,
129     VMHEAP_HRT,
130     VMHEAP_UNKNOWN_MAP,
131     VMHEAP_GRAPHICS,
132     VMHEAP_GL,
133     VMHEAP_OTHER_MEMTRACK,
134 
135     // extra sections (heap).
136     VMHEAP_SENSITIVE_VM_NORMAL,
137     VMHEAP_SENSITIVE_VM_LARGE,
138     VMHEAP_SENSITIVE_VM_ZYGOTE,
139     VMHEAP_SENSITIVE_VM_NON_MOVING,
140 
141     // other extra sections.
142     VMHEAP_SENSITIVE_VM_OTHER_LINEARALLOC,
143     VMHEAP_SENSITIVE_VM_OTHER_ACCOUNTING,
144     VMHEAP_SENSITIVE_VM_OTHER_ZYGOTE_CODE_CACHE,
145     VMHEAP_SENSITIVE_VM_OTHER_APP_CODE_CACHE,
146     VMHEAP_SENSITIVE_VM_OTHER_COMPILER_METADATA,
147     VMHEAP_SENSITIVE_VM_OTHER_INDIRECT_REFERENCE_TABLE,
148 
149     VMHEAP_SENSITIVE_JVBIN_BOOT_VDEX,
150     VMHEAP_SENSITIVE_JVBIN_APP_SENSITIVE_JVBIN,
151     VMHEAP_SENSITIVE_JVBIN_APP_VDEX,
152 
153     // App hrt, boot hrt.
154     VMHEAP_HRT_APP,
155     VMHEAP_HRT_BOOT,
156 
157     VMHEAP_NUM_HEAP,
158     VMHEAP_NUM_EXCLUSIVE_HEAP = VMHEAP_OTHER_MEMTRACK + 1,
159     VMHEAP_NUM_CORE_HEAP = VMHEAP_NATIVE + 1
160 };
161 
162 enum OpsType {
163     OPS_START = 1,
164     OPS_END,
165 };
166 
167 struct VmeminfoAreaMapping {
168     int ops;
169     const char* heapstr;
170     int heapid[2];
171 };
172 
173 constexpr VmeminfoAreaMapping g_vmaMemHeap[] = {
174     {OpsType::OPS_START, "[heap]", {VmemifoType::VMHEAP_NATIVE, VmemifoType::VMHEAP_NULL}},
175     {OpsType::OPS_START, "[stack", {VmemifoType::VMHEAP_STACK, VmemifoType::VMHEAP_NULL}},
176 };
177 
178 // [anon:
179 constexpr VmeminfoAreaMapping g_vmaMemAnon[] = {
180     {OpsType::OPS_START, "[anon:libc_malloc]", {VmemifoType::VMHEAP_NATIVE, VmemifoType::VMHEAP_NULL}},
181     {OpsType::OPS_START, "[anon:scudo:", {VmemifoType::VMHEAP_NATIVE, VmemifoType::VMHEAP_NULL}},
182     {OpsType::OPS_START, "[anon:GWP-ASan", {VmemifoType::VMHEAP_NATIVE, VmemifoType::VMHEAP_NULL}},
183     {OpsType::OPS_START, "[anon:stack_and_tls:", {VmemifoType::VMHEAP_STACK, VmemifoType::VMHEAP_NULL}},
184     {OpsType::OPS_START,
185      "[anon:sensitive_vm-LinearAlloc",
186      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_LINEARALLOC}},
187     {OpsType::OPS_START,
188      "[anon:sensitive_vm-alloc space", {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_NORMAL}},
189     {OpsType::OPS_START,
190      "[anon:sensitive_vm-main space", {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_NORMAL}},
191     {OpsType::OPS_START,
192      "[anon:sensitive_vm-large object space",
193      {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_LARGE}},
194     {OpsType::OPS_START,
195      "[anon:sensitive_vm-free list large object space",
196      {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_LARGE}},
197     {OpsType::OPS_START,
198      "[anon:sensitive_vm-non moving space",
199      {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_NON_MOVING}},
200     {OpsType::OPS_START,
201      "[anon:sensitive_vm-zygote space", {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_ZYGOTE}},
202     {OpsType::OPS_START,
203      "[anon:sensitive_vm-indirect ref",
204      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_INDIRECT_REFERENCE_TABLE}},
205     {OpsType::OPS_START,
206      "[anon:sensitive_vm-jit-code-cache",
207      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_APP_CODE_CACHE}},
208     {OpsType::OPS_START,
209      "[anon:sensitive_vm-data-code-cache",
210      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_APP_CODE_CACHE}},
211     {OpsType::OPS_START,
212      "[anon:sensitive_vm-CompilerMetadata",
213      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_COMPILER_METADATA}},
214     {OpsType::OPS_START,
215      "[anon:sensitive_vm-",
216      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_ACCOUNTING}},
217     {OpsType::OPS_START, "[anon:", {VmemifoType::VMHEAP_UNKNOWN, VmemifoType::VMHEAP_NULL}},
218 };
219 
220 constexpr VmeminfoAreaMapping g_vmaMemFd[] = {
221     {OpsType::OPS_START,
222      "/memfd:jit-cache",
223      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_APP_CODE_CACHE}},
224     {OpsType::OPS_START,
225      "/memfd:jit-zygote-cache",
226      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_ZYGOTE_CODE_CACHE}},
227 };
228 // dev
229 constexpr VmeminfoAreaMapping g_vmaMemDev[] = {
230     {OpsType::OPS_START, "/dev/kgsl-3d0", {VmemifoType::VMHEAP_GL_DEV, VmemifoType::VMHEAP_NULL}},
231     {OpsType::OPS_START, "/dev/ashmem/CursorWindow", {VmemifoType::VMHEAP_CURSOR, VmemifoType::VMHEAP_NULL}},
232     {OpsType::OPS_START,
233      "/dev/ashmem/jit-zygote-cache",
234      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_ZYGOTE_CODE_CACHE}},
235     {OpsType::OPS_START, "/dev/ashmem", {VmemifoType::VMHEAP_ASHMEM, VmemifoType::VMHEAP_NULL}},
236     {OpsType::OPS_START, "/dev/", {VmemifoType::VMHEAP_UNKNOWN_DEV, VmemifoType::VMHEAP_NULL}},
237 };
238 
239 constexpr VmeminfoAreaMapping g_vmaMemSuffix[] = {
240     {OpsType::OPS_END, ".so", {VmemifoType::VMHEAP_SO, VmemifoType::VMHEAP_NULL}},
241     {OpsType::OPS_END, ".so.1", {VmemifoType::VMHEAP_SO, VmemifoType::VMHEAP_NULL}},
242     {OpsType::OPS_END, ".jar", {VmemifoType::VMHEAP_JAR, VmemifoType::VMHEAP_NULL}},
243     {OpsType::OPS_END, ".ttf", {VmemifoType::VMHEAP_TTF, VmemifoType::VMHEAP_NULL}},
244     {OpsType::OPS_END, ".oat", {VmemifoType::VMHEAP_OAT, VmemifoType::VMHEAP_NULL}},
245 
246     {OpsType::OPS_END,
247      ".odex", {VmemifoType::VMHEAP_SENSITIVE_JVBIN, VmemifoType::VMHEAP_SENSITIVE_JVBIN_APP_SENSITIVE_JVBIN}},
248 
249     {OpsType::OPS_END, ".vdex", {VmemifoType::VMHEAP_SENSITIVE_JVBIN, VmemifoType::VMHEAP_NEEDFIX}},
250     {OpsType::OPS_END, ".hrt", {VmemifoType::VMHEAP_HRT, VmemifoType::VMHEAP_NEEDFIX}},
251     {OpsType::OPS_END, ".hrt]", {VmemifoType::VMHEAP_HRT, VmemifoType::VMHEAP_NEEDFIX}},
252 };
253 
254 class SmapsStats {
255 public:
SmapsStats()256     SmapsStats() {}
SmapsStats(const std::string path)257     SmapsStats(const std::string path) : testpath_(path){};
~SmapsStats()258     ~SmapsStats() {}
259     bool ParseMaps(int pid);
260     int GetProcessJavaHeap();
261     int GetProcessNativeHeap();
262     int GetProcessCode();
263     int GetProcessStack();
264     int GetProcessGraphics();
265     int GetProcessPrivateOther();
266     int GetProcessSystem();
267 
268 private:
269     std::array<StatsInfo, VMHEAP_NUM_HEAP> stats_;
270     bool lastline_ = false;
271     std::string testpath_;
272 
273     int GetTotalPrivateClean();
274     int GetTotalPrivateDirty();
275     int GetPrivate(int type);
276     int GetTotalPss();
277     int GetTotalSwappedOutPss();
278     void ReviseStatsData();
279 
280     bool ReadVmemareasFile(const std::string& path);
281     bool ParseMapHead(std::string& line, MapPiecesInfo& head);
282     bool SetMapAddrInfo(std::string& line, MapPiecesInfo& head);
283     bool GetMemUsageField(std::string& line, MemUsageInfo& memusage);
284     void CollectVmemAreasData(const MapPiecesInfo& mempic,
285                               const MemUsageInfo& memusage,
286                               uint64_t& prevEnd,
287                               int& prevHeap);
288     bool GetVmaIndex(std::string name, uint32_t namesz, int32_t heapIndex[2], bool& swappable);
289     uint64_t GetSwapablepssValue(const MemUsageInfo& memusage, bool swappable);
290     void SetVmemAreasData(int index, uint64_t swapablePss, const MemUsageInfo& usage);
291     void HeapIndexFix(std::string name, const char* key, int32_t heapIndex[2]);
292     bool GetVMAStuId(int ops,
293                      std::string name,
294                      const VmeminfoAreaMapping vma[],
295                      int count,
296                      int32_t heapIndex[2],
297                      bool& swappable);
298 };
299 
300 #endif