• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "executor/memory/smaps_memory_info.h"
16 
17 #include <cinttypes>
18 #include <fstream>
19 #include <numeric>
20 #include <thread>
21 #include <v1_0/imemory_tracker_interface.h>
22 #include <cstring>
23 
24 #include "dump_common_utils.h"
25 #include "dump_utils.h"
26 #include "executor/memory/get_cma_info.h"
27 #include "executor/memory/get_hardware_info.h"
28 #include "executor/memory/get_kernel_info.h"
29 #include "executor/memory/get_process_info.h"
30 #include "executor/memory/get_ram_info.h"
31 #include "executor/memory/memory_util.h"
32 #include "executor/memory/parse/meminfo_data.h"
33 #include "executor/memory/parse/parse_meminfo.h"
34 #include "executor/memory/parse/parse_smaps_rollup_info.h"
35 #include "executor/memory/parse/parse_smaps_info.h"
36 #include "hdf_base.h"
37 #include "hilog_wrapper.h"
38 #include "securec.h"
39 #include "string_ex.h"
40 #include "util/string_utils.h"
41 
42 using namespace std;
43 using namespace OHOS::HDI::Memorytracker::V1_0;
44 namespace OHOS {
45 namespace HiviewDFX {
46 static constexpr int LINE_WIDTH = 12;
47 static constexpr int LINE_NAME_VAL_WIDTH = 60;
48 static constexpr int LINE_START_VAL_WIDTH = 18;
49 static constexpr int LINE_NAME_V_WIDTH = 16;
50 static constexpr int LINE_MEMORY_CLASS_WIDTH = 15;
51 static constexpr size_t TYPE_SIZE = 2;
52 static constexpr size_t TYPE_MIN_SIZE = 1;
53 static constexpr char BLANK = ' ';
SmapsMemoryInfo()54 SmapsMemoryInfo::SmapsMemoryInfo()
55 {
56 }
57 
~SmapsMemoryInfo()58 SmapsMemoryInfo::~SmapsMemoryInfo()
59 {
60 }
61 
InsertSmapsTitle(StringMatrix result,bool isShowSmapsInfo)62 void SmapsMemoryInfo::InsertSmapsTitle(StringMatrix result, bool isShowSmapsInfo)
63 {
64     vector<string> line1;
65     vector<string> line2;
66     vector<string> titleVec = isShowSmapsInfo ? MemoryFilter::GetInstance().TITLE_V_SMAPS_HAS_PID_ :
67         MemoryFilter::GetInstance().TITLE_SMAPS_HAS_PID_;
68     if (DumpUtils::IsUserMode()) {
69         titleVec.erase(std::remove(titleVec.begin(), titleVec.end(), "Perm"), titleVec.end());
70         titleVec.erase(std::remove(titleVec.begin(), titleVec.end(), "Start"), titleVec.end());
71         titleVec.erase(std::remove(titleVec.begin(), titleVec.end(), "End"), titleVec.end());
72     }
73     for (string str : titleVec) {
74         vector<string> types;
75         StringUtils::GetInstance().StringSplit(str, "_", types);
76         if (types.size() == TYPE_SIZE) {
77             string title1 = types.at(0);
78             StringUtils::GetInstance().SetWidth(LINE_WIDTH, BLANK, true, title1);
79             line1.push_back(title1);
80             string title2 = types.at(1);
81             StringUtils::GetInstance().SetWidth(LINE_WIDTH, BLANK, true, title2);
82             line2.push_back(title2);
83         } else if (types.size() == TYPE_MIN_SIZE) {
84             string title = types.at(0);
85             string space = " ";
86             StringUtils::GetInstance().SetWidth(LINE_WIDTH, BLANK, true, space);
87             line1.push_back(space);
88             constexpr int LINE_NAME_KEY_WIDTH = 22;
89             if (StringUtils::GetInstance().IsSameStr(title, "Name")) {
90                 StringUtils::GetInstance().SetWidth(isShowSmapsInfo ? LINE_NAME_V_WIDTH : LINE_NAME_KEY_WIDTH,
91                     BLANK, false, title);
92             } else if (StringUtils::GetInstance().IsSameStr(title, "Category")) {
93                 StringUtils::GetInstance().SetWidth(LINE_MEMORY_CLASS_WIDTH, BLANK, true, title);
94             } else {
95                 StringUtils::GetInstance().SetWidth(StringUtils::GetInstance().IsSameStr(title, "Start") ?
96                     LINE_START_VAL_WIDTH : LINE_WIDTH, BLANK, true, title);
97             }
98             line2.push_back(title);
99         }
100     }
101     result->push_back(line1);
102     result->push_back(line2);
103 }
104 
SetValueForRet(const std::string & value,const int & width,std::vector<std::string> & tempResult)105 void SmapsMemoryInfo::SetValueForRet(const std::string& value, const int &width, std::vector<std::string>& tempResult)
106 {
107     std::string tempStr = value;
108     StringUtils::GetInstance().SetWidth(width, BLANK, true, tempStr);
109     tempResult.push_back(tempStr);
110 }
111 
SetOneRowMemInfo(const MemoryData & memInfo,bool isShowSmapsInfo,bool isSummary,StringMatrix result)112 void SmapsMemoryInfo::SetOneRowMemInfo(const MemoryData &memInfo, bool isShowSmapsInfo,
113     bool isSummary, StringMatrix result)
114 {
115     vector<string> tempResult;
116     SetValueForRet(to_string(memInfo.size), LINE_WIDTH, tempResult);
117     SetValueForRet(to_string(memInfo.rss), LINE_WIDTH, tempResult);
118     SetValueForRet(to_string(memInfo.pss), LINE_WIDTH, tempResult);
119     SetValueForRet(to_string(memInfo.sharedClean), LINE_WIDTH, tempResult);
120     SetValueForRet(to_string(memInfo.sharedDirty), LINE_WIDTH, tempResult);
121     SetValueForRet(to_string(memInfo.privateClean), LINE_WIDTH, tempResult);
122     SetValueForRet(to_string(memInfo.privateDirty), LINE_WIDTH, tempResult);
123     SetValueForRet(to_string(memInfo.swap), LINE_WIDTH, tempResult);
124     SetValueForRet(to_string(memInfo.swapPss), LINE_WIDTH, tempResult);
125     if (isShowSmapsInfo) {
126         if (!DumpUtils::IsUserMode()) {
127             SetValueForRet(memInfo.permission, LINE_WIDTH, tempResult);
128             SetValueForRet(memInfo.startAddr, LINE_START_VAL_WIDTH, tempResult);
129             SetValueForRet(memInfo.endAddr, LINE_WIDTH, tempResult);
130         }
131     } else {
132         SetValueForRet(to_string(memInfo.counts), LINE_WIDTH, tempResult);
133     }
134     // set memory class
135     string memoryClass = memInfo.memoryClass;
136     if (memoryClass == "other") {
137         if (memInfo.iNode == 0) {
138             memoryClass = "AnonPage other";
139         } else {
140             memoryClass = "FilePage other";
141         }
142     }
143     SetValueForRet(memoryClass, LINE_MEMORY_CLASS_WIDTH, tempResult);
144     // set name
145     string space = " ";
146     StringUtils::GetInstance().SetWidth(isShowSmapsInfo ? LINE_WIDTH : LINE_START_VAL_WIDTH, BLANK, false, space);
147     string value = isSummary ? "Summary" : memInfo.name;
148     value = space + value;
149     StringUtils::GetInstance().SetWidth(LINE_NAME_VAL_WIDTH, BLANK, true, value);
150     tempResult.push_back(value);
151 
152     // set one row data
153     result->push_back(tempResult);
154 }
155 
UpdateShowAddressMemInfoResult(const std::vector<MemoryData> & showAddressMemInfoVec,StringMatrix result)156 void SmapsMemoryInfo::UpdateShowAddressMemInfoResult(const std::vector<MemoryData>& showAddressMemInfoVec,
157     StringMatrix result)
158 {
159     MemoryData summary;
160     for (const auto &memInfo : showAddressMemInfoVec) {
161         summary.size += memInfo.size;
162         summary.rss += memInfo.rss;
163         summary.pss += memInfo.pss;
164         summary.sharedClean += memInfo.sharedClean;
165         summary.sharedDirty += memInfo.sharedDirty;
166         summary.privateClean += memInfo.privateClean;
167         summary.privateDirty += memInfo.privateDirty;
168         summary.swap += memInfo.swap;
169         summary.swapPss += memInfo.swapPss;
170         SetOneRowMemInfo(memInfo, true, false, result);
171     }
172     summary.pss += summary.swapPss;
173     SetOneRowMemInfo(summary, true, true, result);
174 }
175 
UpdateCountSameNameMemResult(std::map<std::string,MemoryData> & countSameNameMemMap,StringMatrix result)176 void SmapsMemoryInfo::UpdateCountSameNameMemResult(std::map<std::string, MemoryData>& countSameNameMemMap,
177     StringMatrix result)
178 {
179     MemoryData summary;
180     for (const auto &memInfo : countSameNameMemMap) {
181         summary.size += memInfo.second.size;
182         summary.rss += memInfo.second.rss;
183         summary.pss += memInfo.second.pss;
184         summary.sharedClean += memInfo.second.sharedClean;
185         summary.sharedDirty += memInfo.second.sharedDirty;
186         summary.privateClean += memInfo.second.privateClean;
187         summary.privateDirty += memInfo.second.privateDirty;
188         summary.swap += memInfo.second.swap;
189         summary.swapPss += memInfo.second.swapPss;
190         summary.counts += memInfo.second.counts;
191         SetOneRowMemInfo(memInfo.second, false, false, result);
192     }
193     summary.pss += summary.swapPss;
194     SetOneRowMemInfo(summary, false, true, result);
195 }
196 
ShowMemorySmapsByPid(const int & pid,StringMatrix result,bool isShowSmapsAddress)197 bool SmapsMemoryInfo::ShowMemorySmapsByPid(const int &pid, StringMatrix result, bool isShowSmapsAddress)
198 {
199     DUMPER_HILOGI(MODULE_SERVICE, "get smaps data begin, pid:%{public}d", pid);
200     std::map<std::string, MemoryData> countSameNameMemMap;
201     std::vector<MemoryData> showAddressMemInfoVec;
202     unique_ptr<ParseSmapsInfo> parseSmapsInfo = make_unique<ParseSmapsInfo>();
203     bool ret = parseSmapsInfo->GetSmapsData(pid, isShowSmapsAddress, countSameNameMemMap, showAddressMemInfoVec);
204     if (!ret) {
205         return false;
206     }
207     InsertSmapsTitle(result, isShowSmapsAddress);
208     if (isShowSmapsAddress) {
209         UpdateShowAddressMemInfoResult(showAddressMemInfoVec, result);
210     } else {
211         UpdateCountSameNameMemResult(countSameNameMemMap, result);
212     }
213     DUMPER_HILOGI(MODULE_SERVICE, "get smaps data end, pid:%{public}d", pid);
214     return true;
215 }
216 } // namespace HiviewDFX
217 } // namespace OHOS