• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 <fstream>
17 #include <sstream>
18 #include "executor/memory/parse/parse_ashmem_info.h"
19 #include "executor/memory/memory_util.h"
20 #include "hilog_wrapper.h"
21 #include "util/file_utils.h"
22 #include "string_ex.h"
23 
24 using namespace std;
25 namespace OHOS {
26 namespace HiviewDFX {
27 const int PHYSICAL_SIZE = 17; // 17 is the length of "physical size is "
28 const int START_POS = 1;
ParseAshmemInfo()29 ParseAshmemInfo::ParseAshmemInfo()
30 {
31 }
32 
~ParseAshmemInfo()33 ParseAshmemInfo::~ParseAshmemInfo()
34 {
35 }
36 
UpdateAshmemOverviewMap(const std::string & line,std::unordered_map<std::string,int64_t> & ashmemOverviewMap)37 void ParseAshmemInfo::UpdateAshmemOverviewMap(
38     const std::string &line, std::unordered_map<std::string, int64_t> &ashmemOverviewMap)
39 {
40     std::string tempLine = line;
41     // delete the whitespace characters at the end of the line
42     size_t lastNonSpace = tempLine.find_last_not_of(' ');
43     if (lastNonSpace != std::string::npos) {
44         tempLine.erase(lastNonSpace + START_POS);
45     }
46     size_t startPos = tempLine.find("[") + START_POS;
47     size_t endPos = tempLine.find("]", startPos);
48     if (startPos == std::string::npos || endPos == std::string::npos || endPos <= startPos) {
49         DUMPER_HILOGE(MODULE_SERVICE, "tempLine is error data, tempLine:%{public}s.", tempLine.c_str());
50         return;
51     }
52     std::string tmpProcessName = tempLine.substr(startPos, endPos - startPos);
53     size_t pos = tempLine.find("physical size is ");
54     if (pos == std::string::npos) {
55         DUMPER_HILOGE(MODULE_SERVICE, "tempLine not find [physical size is], tempLine:%{public}s.", tempLine.c_str());
56         return;
57     }
58     std::string physicalSize = tempLine.substr(pos + PHYSICAL_SIZE);
59     if (!IsNumericStr(physicalSize)) {
60         DUMPER_HILOGE(MODULE_SERVICE, "physicalSize is not number, physicalSize:%{public}s.", physicalSize.c_str());
61         return;
62     }
63     int64_t pss = 0;
64     if (!StringUtils::GetInstance().IsStringToIntSuccess(physicalSize, pss)) {
65         DUMPER_HILOGE(MODULE_SERVICE, "physicalSize is too big, physicalSize:%{public}s.", physicalSize.c_str());
66         return;
67     }
68     ashmemOverviewMap[tmpProcessName] = pss;
69 }
70 
GetAshmemInfo(const int32_t & pid,pair<int,vector<string>> & result)71 bool ParseAshmemInfo::GetAshmemInfo(const int32_t &pid, pair<int, vector<string>> &result)
72 {
73     DUMPER_HILOGD(MODULE_SERVICE, "GetAshmemInfo begin, pid:%{public}d", pid);
74     bool inDetailSection = false;
75     std::string path = "/proc/ashmem_process_info";
76     std::string processName = "unknown";
77     std::string detailTitle = "";
78     std::vector<string> details;
79     std::unordered_map<std::string, int64_t> ashmemOverviewMap;
80     bool ret = FileUtils::GetInstance().LoadStringFromProcCb(path, false, true, [&](const string &line) -> void {
81         if (line.find("Total ashmem  of") != std::string::npos) {
82             UpdateAshmemOverviewMap(line, ashmemOverviewMap);
83         }
84         if (line.find("Process_name") != std::string::npos) {
85             detailTitle = line;
86             inDetailSection = true;
87             return;
88         }
89         if (inDetailSection) {
90             std::istringstream lineStream(line);
91             int targetPid = 0;
92             std::string name;
93             lineStream >> name >> targetPid;
94             if (pid == targetPid) {
95                 processName = name;
96                 details.push_back(line);
97             }
98         }
99     });
100     if (details.empty()) {
101         DUMPER_HILOGE(MODULE_SERVICE, "detail ashmem is empty.");
102         return false;
103     }
104     details.insert(details.begin(), detailTitle);
105     if (ashmemOverviewMap.find(processName) == ashmemOverviewMap.end()) {
106         DUMPER_HILOGE(MODULE_SERVICE, "not find processName:%{public}s.", processName.c_str());
107         return false;
108     }
109     result.first = ashmemOverviewMap[processName] / static_cast<int64_t>(MemoryUtil::GetInstance().BYTE_TO_KB_); // KB
110     result.second = details;
111     DUMPER_HILOGD(MODULE_SERVICE, "GetAshmemInfo end, pid:%{public}d, ret:%{public}d", pid, ret);
112     return ret;
113 }
114 } // namespace HiviewDFX
115 } // namespace OHOS