• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 "memory_catcher.h"
16 
17 #include "collect_result.h"
18 #include "file_util.h"
19 #include "freeze_common.h"
20 #include "hiview_logger.h"
21 #include "memory_collector.h"
22 #include "string_util.h"
23 
24 namespace OHOS {
25 namespace HiviewDFX {
26 namespace {
27     constexpr const char* ASHMEM_PATH = "/proc/ashmem_process_info";
28     constexpr const char* DMAHEAP_PATH = "/proc/dmaheap_process_info";
29     constexpr const char* GPUMEM_PATH = "/proc/gpumem_process_info";
30     constexpr const char* ASHMEM = "AshmemUsed";
31     constexpr const char* DMAHEAP = "DmaHeapTotalUsed";
32     constexpr const char* GPUMEM = "GpuTotalUsed";
33     constexpr const char* RECLAIM = "ReclaimAvailBuffer";
34     constexpr const char* LONG_PRESS = "LONG_PRESS";
35     constexpr const char* AP_S_PRESS6S = "AP_S_PRESS6S";
36     constexpr const char* PROC_PRESSURE_MEMORY = "/proc/pressure/memory";
37     constexpr const char* PROC_MEMORYVIEW = "/proc/memview";
38     constexpr const char* PROC_MEMORYINFO = "/proc/meminfo";
39     constexpr int OVER_MEM_SIZE = 2 * 1024 * 1024;
40     constexpr int BELOW_MEM_SIZE = 500 * 1024;
41     constexpr int DECIMAL = 10;
42 }
43 #ifdef USAGE_CATCHER_ENABLE
44 using namespace UCollect;
45 using namespace UCollectUtil;
46 DEFINE_LOG_LABEL(0xD002D01, "EventLogger-MemoryCatcher");
MemoryCatcher()47 MemoryCatcher::MemoryCatcher() : EventLogCatcher()
48 {
49     name_ = "MemoryCatcher";
50 }
51 
Initialize(const std::string & strParam1,int intParam1,int intParam2)52 bool MemoryCatcher::Initialize(const std::string& strParam1, int intParam1, int intParam2)
53 {
54     // this catcher do not need parameters, just return true
55     description_ = "MemoryCatcher --\n";
56     return true;
57 }
58 
Catch(int fd,int jsonFd)59 int MemoryCatcher::Catch(int fd, int jsonFd)
60 {
61     int originSize = GetFdSize(fd);
62     std::string freezeMemory;
63     std::string content;
64     if (event_) {
65         freezeMemory = event_->GetEventValue("FREEZE_MEMORY");
66         size_t tagIndex = freezeMemory.find("Get freeze memory end time:");
67         std::string splitStr = "\\n";
68         size_t procStatmIndex = freezeMemory.rfind(splitStr);
69         if (tagIndex != std::string::npos && procStatmIndex != std::string::npos && procStatmIndex > tagIndex) {
70             content = freezeMemory.substr(0, procStatmIndex);
71             event_->SetEventValue("PROC_STATM", freezeMemory.substr(procStatmIndex + splitStr.size()));
72         }
73     }
74     content = freezeMemory.empty() ? CollectFreezeSysMemory() : content;
75     std::string data;
76     if (!content.empty()) {
77         std::vector<std::string> vec;
78         StringUtil::SplitStr(content, "\\n", vec);
79         for (const std::string& mem : vec) {
80             FileUtil::SaveStringToFd(fd, mem + "\n");
81             CheckString(mem, data, ASHMEM, ASHMEM_PATH);
82             CheckString(mem, data, DMAHEAP, DMAHEAP_PATH);
83             CheckString(mem, data, GPUMEM, GPUMEM_PATH);
84             CheckString(mem, data, RECLAIM, "");
85         }
86     }
87     if (!data.empty()) {
88         FreezeCommon::WriteTimeInfoToFd(fd, "collect ashmem dmaheap gpumem start time: ");
89         FileUtil::SaveStringToFd(fd, data);
90         FreezeCommon::WriteTimeInfoToFd(fd, "\ncollect ashmem dmaheap gpumem end time: ", false);
91     } else {
92         FileUtil::SaveStringToFd(fd, "don't collect ashmem dmaheap gpumem\n");
93     }
94     logSize_ = GetFdSize(fd) - originSize;
95     return logSize_;
96 }
97 
CollectMemInfo()98 void MemoryCatcher::CollectMemInfo()
99 {
100     HIVIEW_LOGI("CollectMemInfo start");
101     std::shared_ptr<MemoryCollector> collector = MemoryCollector::Create();
102     collector->CollectRawMemInfo();
103     collector->ExportMemView();
104     HIVIEW_LOGI("CollectMemInfo end");
105 }
106 
SetEvent(std::shared_ptr<SysEvent> event)107 void MemoryCatcher::SetEvent(std::shared_ptr<SysEvent> event)
108 {
109     event_ = event;
110 }
111 
GetStringFromFile(const std::string & path)112 std::string MemoryCatcher::GetStringFromFile(const std::string &path)
113 {
114     std::string content;
115     FileUtil::LoadStringFromFile(path, content);
116     return content;
117 }
118 
GetNumFromString(const std::string & mem)119 int MemoryCatcher::GetNumFromString(const std::string &mem)
120 {
121     int num = 0;
122     int digit = 0;
123     int maxDivTen = INT_MAX / DECIMAL;
124     int maxLastDigit = INT_MAX % DECIMAL;
125 
126     for (const char &c : mem) {
127         if (!isdigit(c)) {
128             continue;
129         }
130         digit = c - '0';
131         if (num > maxDivTen || (num == maxDivTen && digit > maxLastDigit)) {
132             return INT_MAX;
133         }
134         num = num * DECIMAL + digit;
135     }
136     return num;
137 }
138 
CheckString(const std::string & mem,std::string & data,const std::string & key,const std::string & path)139 void MemoryCatcher::CheckString(
140     const std::string &mem, std::string &data, const std::string &key, const std::string &path)
141 {
142     if (mem.find(key) != std::string::npos) {
143         int memsize = GetNumFromString(mem);
144         if (!path.empty() && memsize > OVER_MEM_SIZE) {
145             data += GetStringFromFile(path);
146         }
147         if (path.empty() && memsize < BELOW_MEM_SIZE && event_) {
148             event_->SetEventValue(FreezeCommon::HOST_RESOURCE_WARNING, "Yes");
149         }
150     }
151 }
152 
CollectFreezeSysMemory()153 std::string MemoryCatcher::CollectFreezeSysMemory()
154 {
155     std::string memInfoPath = FileUtil::FileExists(PROC_MEMORYVIEW) ? PROC_MEMORYVIEW : PROC_MEMORYINFO;
156     std::string content = GetStringFromFile(PROC_PRESSURE_MEMORY) + "\n" + GetStringFromFile(memInfoPath);
157     return content;
158 }
159 #endif // USAGE_CATCHER_ENABLE
160 } // namespace HiviewDFX
161 } // namespace OHOS
162