• 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:native_heap:", {VmemifoType::VMHEAP_NATIVE, VmemifoType::VMHEAP_NULL}},
182     {OpsType::OPS_START, "[anon:scudo:", {VmemifoType::VMHEAP_NATIVE, VmemifoType::VMHEAP_NULL}},
183     {OpsType::OPS_START, "[anon:GWP-ASan", {VmemifoType::VMHEAP_NATIVE, VmemifoType::VMHEAP_NULL}},
184     {OpsType::OPS_START, "[anon:stack_and_tls:", {VmemifoType::VMHEAP_STACK, VmemifoType::VMHEAP_NULL}},
185     {OpsType::OPS_START,
186      "[anon:sensitive_vm-LinearAlloc",
187      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_LINEARALLOC}},
188     {OpsType::OPS_START,
189      "[anon:sensitive_vm-alloc space", {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_NORMAL}},
190     {OpsType::OPS_START,
191      "[anon:sensitive_vm-main space", {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_NORMAL}},
192     {OpsType::OPS_START,
193      "[anon:sensitive_vm-large object space",
194      {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_LARGE}},
195     {OpsType::OPS_START,
196      "[anon:sensitive_vm-free list large object space",
197      {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_LARGE}},
198     {OpsType::OPS_START,
199      "[anon:sensitive_vm-non moving space",
200      {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_NON_MOVING}},
201     {OpsType::OPS_START,
202      "[anon:sensitive_vm-zygote space", {VmemifoType::VMHEAP_SENSITIVE_VM, VmemifoType::VMHEAP_SENSITIVE_VM_ZYGOTE}},
203     {OpsType::OPS_START,
204      "[anon:sensitive_vm-indirect ref",
205      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_INDIRECT_REFERENCE_TABLE}},
206     {OpsType::OPS_START,
207      "[anon:sensitive_vm-jit-code-cache",
208      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_APP_CODE_CACHE}},
209     {OpsType::OPS_START,
210      "[anon:sensitive_vm-data-code-cache",
211      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_APP_CODE_CACHE}},
212     {OpsType::OPS_START,
213      "[anon:sensitive_vm-CompilerMetadata",
214      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_COMPILER_METADATA}},
215     {OpsType::OPS_START,
216      "[anon:sensitive_vm-",
217      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_ACCOUNTING}},
218     {OpsType::OPS_START, "[anon:", {VmemifoType::VMHEAP_UNKNOWN, VmemifoType::VMHEAP_NULL}},
219 };
220 
221 constexpr VmeminfoAreaMapping g_vmaMemFd[] = {
222     {OpsType::OPS_START,
223      "/memfd:jit-cache",
224      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_APP_CODE_CACHE}},
225     {OpsType::OPS_START,
226      "/memfd:jit-zygote-cache",
227      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_ZYGOTE_CODE_CACHE}},
228 };
229 // dev
230 constexpr VmeminfoAreaMapping g_vmaMemDev[] = {
231     {OpsType::OPS_START, "/dev/kgsl-3d0", {VmemifoType::VMHEAP_GL_DEV, VmemifoType::VMHEAP_NULL}},
232     {OpsType::OPS_START, "/dev/ashmem/CursorWindow", {VmemifoType::VMHEAP_CURSOR, VmemifoType::VMHEAP_NULL}},
233     {OpsType::OPS_START,
234      "/dev/ashmem/jit-zygote-cache",
235      {VmemifoType::VMHEAP_SENSITIVE_VM_OTHER, VmemifoType::VMHEAP_SENSITIVE_VM_OTHER_ZYGOTE_CODE_CACHE}},
236     {OpsType::OPS_START, "/dev/ashmem", {VmemifoType::VMHEAP_ASHMEM, VmemifoType::VMHEAP_NULL}},
237     {OpsType::OPS_START, "/dev/", {VmemifoType::VMHEAP_UNKNOWN_DEV, VmemifoType::VMHEAP_NULL}},
238 };
239 
240 constexpr VmeminfoAreaMapping g_vmaMemSuffix[] = {
241     {OpsType::OPS_END, ".so", {VmemifoType::VMHEAP_SO, VmemifoType::VMHEAP_NULL}},
242     {OpsType::OPS_END, ".so.1", {VmemifoType::VMHEAP_SO, VmemifoType::VMHEAP_NULL}},
243     {OpsType::OPS_END, ".jar", {VmemifoType::VMHEAP_JAR, VmemifoType::VMHEAP_NULL}},
244     {OpsType::OPS_END, ".ttf", {VmemifoType::VMHEAP_TTF, VmemifoType::VMHEAP_NULL}},
245     {OpsType::OPS_END, ".oat", {VmemifoType::VMHEAP_OAT, VmemifoType::VMHEAP_NULL}},
246 
247     {OpsType::OPS_END,
248      ".odex", {VmemifoType::VMHEAP_SENSITIVE_JVBIN, VmemifoType::VMHEAP_SENSITIVE_JVBIN_APP_SENSITIVE_JVBIN}},
249 
250     {OpsType::OPS_END, ".vdex", {VmemifoType::VMHEAP_SENSITIVE_JVBIN, VmemifoType::VMHEAP_NEEDFIX}},
251     {OpsType::OPS_END, ".hrt", {VmemifoType::VMHEAP_HRT, VmemifoType::VMHEAP_NEEDFIX}},
252     {OpsType::OPS_END, ".hrt]", {VmemifoType::VMHEAP_HRT, VmemifoType::VMHEAP_NEEDFIX}},
253 };
254 
255 class SmapsStats {
256 public:
SmapsStats()257     SmapsStats() {}
SmapsStats(const std::string path)258     SmapsStats(const std::string path) : testpath_(path){};
~SmapsStats()259     ~SmapsStats() {}
260     bool ParseMaps(int pid);
261     int GetProcessJavaHeap();
262     int GetProcessNativeHeap();
263     int GetProcessCode();
264     int GetProcessStack();
265     int GetProcessGraphics();
266     int GetProcessPrivateOther();
267     int GetProcessSystem();
268 
269 private:
270     std::array<StatsInfo, VMHEAP_NUM_HEAP> stats_;
271     bool lastline_ = false;
272     std::string testpath_;
273 
274     int GetTotalPrivateClean();
275     int GetTotalPrivateDirty();
276     int GetPrivate(int type);
277     int GetTotalPss();
278     int GetTotalSwappedOutPss();
279     void ReviseStatsData();
280 
281     bool ReadVmemareasFile(const std::string& path);
282     bool ParseMapHead(std::string& line, MapPiecesInfo& head);
283     bool SetMapAddrInfo(std::string& line, MapPiecesInfo& head);
284     bool GetMemUsageField(std::string& line, MemUsageInfo& memusage);
285     void CollectVmemAreasData(const MapPiecesInfo& mempic,
286                               const MemUsageInfo& memusage,
287                               uint64_t& prevEnd,
288                               int& prevHeap);
289     bool GetVmaIndex(std::string name, uint32_t namesz, int32_t heapIndex[2], bool& swappable);
290     uint64_t GetSwapablepssValue(const MemUsageInfo& memusage, bool swappable);
291     void SetVmemAreasData(int index, uint64_t swapablePss, const MemUsageInfo& usage);
292     void HeapIndexFix(std::string name, const char* key, int32_t heapIndex[2]);
293     bool GetVMAStuId(int ops,
294                      std::string name,
295                      const VmeminfoAreaMapping vma[],
296                      int count,
297                      int32_t heapIndex[2],
298                      bool& swappable);
299 };
300 
301 #endif