1 /*
2 * Copyright (C) 2021-2022 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 #include "executor/memory/parse/parse_smaps_info.h"
17 #include <fstream>
18 #include "executor/memory/memory_util.h"
19 #include "hilog_wrapper.h"
20 #include "util/string_utils.h"
21
22 using namespace std;
23 namespace OHOS {
24 namespace HiviewDFX {
ParseSmapsInfo()25 ParseSmapsInfo::ParseSmapsInfo()
26 {
27 }
28
~ParseSmapsInfo()29 ParseSmapsInfo::~ParseSmapsInfo()
30 {
31 }
32
GetHasPidValue(const string & str,string & type,uint64_t & value)33 bool ParseSmapsInfo::GetHasPidValue(const string &str, string &type, uint64_t &value)
34 {
35 bool success = false;
36 if (StringUtils::GetInstance().IsBegin(str, "R")) {
37 success = MemoryUtil::GetInstance().GetTypeAndValue(str, type, value);
38 if (success) {
39 if (type == "Rss") {
40 return true;
41 }
42 }
43 return false;
44 } else if (StringUtils::GetInstance().IsBegin(str, "P")) {
45 success = MemoryUtil::GetInstance().GetTypeAndValue(str, type, value);
46 if (success) {
47 if (type == "Pss" || type == "Private_Clean" || type == "Private_Dirty") {
48 return true;
49 }
50 }
51 return false;
52 } else if (StringUtils::GetInstance().IsBegin(str, "S")) {
53 success = MemoryUtil::GetInstance().GetTypeAndValue(str, type, value);
54 if (success) {
55 if (type == "Shared_Clean" || type == "Shared_Dirty" || type == "Swap" || type == "SwapPss") {
56 return true;
57 }
58 }
59 return false;
60 }
61 return false;
62 }
63
GetNoPidValue(const string & str,string & type,uint64_t & value)64 bool ParseSmapsInfo::GetNoPidValue(const string &str, string &type, uint64_t &value)
65 {
66 if (StringUtils::GetInstance().IsBegin(str, "Pss") || StringUtils::GetInstance().IsBegin(str, "SwapPss")) {
67 return MemoryUtil::GetInstance().GetTypeAndValue(str, type, value);
68 }
69 return false;
70 }
71
GetValue(const MemoryFilter::MemoryType & memType,const string & str,string & type,uint64_t & value)72 bool ParseSmapsInfo::GetValue(const MemoryFilter::MemoryType &memType, const string &str, string &type, uint64_t &value)
73 {
74 if (memType == MemoryFilter::MemoryType::APPOINT_PID) {
75 return GetHasPidValue(str, type, value);
76 } else {
77 return GetNoPidValue(str, type, value);
78 }
79 }
80
81 /**
82 * @description: Parse smaps file
83 * @param {MemoryType} &memType-APPOINT_PID-Specify the PID,NOT_SPECIFIED_PID-No PID is specified
84 * @param {int} &pid-Pid
85 * @param {GroupMap} &result-The result of parsing
86 * @return bool-true:parse success,false-parse fail
87 */
GetInfo(const MemoryFilter::MemoryType & memType,const int & pid,GroupMap & result)88 bool ParseSmapsInfo::GetInfo(const MemoryFilter::MemoryType &memType, const int &pid, GroupMap &result)
89 {
90 DUMPER_HILOGD(MODULE_SERVICE, "ParseSmapsInfo: GetInfo pid:(%d) begin.\n", pid);
91 string filename = "/proc/" + to_string(pid) + "/smaps";
92 ifstream in(filename);
93 if (!in) {
94 DUMPER_HILOGE(MODULE_SERVICE, "File %s not found.\n", filename.c_str());
95 return false;
96 }
97
98 string content;
99 while (getline(in, content)) {
100 string name;
101 uint64_t iNode = 0;
102 if (StringUtils::GetInstance().IsEnd(content, "B")) {
103 string type;
104 uint64_t value = 0;
105 if (GetValue(memType, content, type, value)) {
106 MemoryUtil::GetInstance().CalcGroup(memGroup_, type, value, result);
107 }
108 } else if (MemoryUtil::GetInstance().IsNameLine(content, name, iNode)) {
109 MemoryFilter::GetInstance().ParseMemoryGroup(name, memGroup_, iNode);
110 }
111 }
112 in.close();
113 DUMPER_HILOGD(MODULE_SERVICE, "ParseSmapsInfo: GetInfo pid:(%d) end,success!\n", pid);
114 return true;
115 }
116 } // namespace HiviewDFX
117 } // namespace OHOS
118