• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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 "native_memory_profiler_sa_client_manager.h"
17 
18 #include "native_memory_profiler_sa_proxy.h"
19 
20 #include "logging.h"
21 
22 #include <iostream>
23 #include <sstream>
24 
25 namespace OHOS::Developtools::NativeDaemon {
26 namespace {
27 constexpr uint32_t LIB_SMS = 4096;
28 constexpr uint32_t CALL_STACK_SMS = 16384;
29 constexpr uint32_t NMD_DURATION = 5;
30 constexpr uint32_t NMD_SHMEM = 300;
31 constexpr int ONLY_NMD = 2;
32 constexpr int SIMP_NMD = 3;
33 constexpr int FIVE_MINUTES = 300;
34 constexpr int JS_STACK_DEPS = 10;
35 }
36 
Start(std::shared_ptr<NativeMemoryProfilerSaConfig> & config)37 int32_t NativeMemoryProfilerSaClientManager::Start(std::shared_ptr<NativeMemoryProfilerSaConfig>& config)
38 {
39     CHECK_NOTNULL(config, RET_ERR, "NativeMemoryProfilerSaClientManager: config is nullptr");
40     CHECK_TRUE(CheckConfig(config), RET_ERR, "CheckConfig failed");
41     auto service = GetRemoteService();
42     if (service == nullptr) {
43         PROFILER_LOG_ERROR(LOG_CORE, "NativeMemoryProfilerSaClientManager: start GetRemoteService failed");
44         return RET_ERR;
45     }
46     NativeMemoryProfilerSaProxy proxy(service);
47     return proxy.Start(config);
48 }
49 
Start(NativeMemProfilerType type,uint32_t pid,uint32_t duration,uint32_t sampleIntervel)50 int32_t NativeMemoryProfilerSaClientManager::Start(NativeMemProfilerType type, uint32_t pid, uint32_t duration,
51     uint32_t sampleIntervel)
52 {
53     if (pid == 0) {
54         PROFILER_LOG_ERROR(LOG_CORE, "NativeMemoryProfilerSaClientManager: pid cannot be 0");
55         return RET_ERR;
56     }
57     auto config = std::make_shared<NativeMemoryProfilerSaConfig>();
58     CHECK_NOTNULL(config, RET_ERR, "NativeMemoryProfilerSaClientManager: config is nullptr");
59     config->pid_ = static_cast<int32_t>(pid);
60     config->duration_ = duration;
61     config->sampleInterval_ = sampleIntervel;
62     if (type == NativeMemProfilerType::MEM_PROFILER_LIBRARY) {
63         config->responseLibraryMode_ = true;
64     } else if (type == NativeMemProfilerType::MEM_PROFILER_CALL_STACK) {
65         config->responseLibraryMode_ = false;
66     }
67     return Start(config);
68 }
69 
Stop(uint32_t pid)70 int32_t NativeMemoryProfilerSaClientManager::Stop(uint32_t pid)
71 {
72     CHECK_TRUE(pid != 0, RET_ERR, "NativeMemoryProfilerSaClientManager: pid is 0");
73     auto service = GetRemoteService();
74     if (service == nullptr) {
75         PROFILER_LOG_ERROR(LOG_CORE, "NativeMemoryProfilerSaClientManager: stop GetRemoteService failed");
76         return RET_ERR;
77     }
78     NativeMemoryProfilerSaProxy proxy(service);
79     return proxy.Stop(pid);
80 }
81 
Stop(const std::string & name)82 int32_t NativeMemoryProfilerSaClientManager::Stop(const std::string& name)
83 {
84     CHECK_TRUE(!name.empty(), RET_ERR, "NativeMemoryProfilerSaClientManager: name is empty");
85     auto service = GetRemoteService();
86     if (service == nullptr) {
87         PROFILER_LOG_ERROR(LOG_CORE, "NativeMemoryProfilerSaClientManager: stop GetRemoteService failed");
88         return RET_ERR;
89     }
90     NativeMemoryProfilerSaProxy proxy(service);
91     return proxy.Stop(name);
92 }
93 
DumpData(uint32_t fd,std::shared_ptr<NativeMemoryProfilerSaConfig> & config)94 int32_t NativeMemoryProfilerSaClientManager::DumpData(uint32_t fd,
95                                                       std::shared_ptr<NativeMemoryProfilerSaConfig>& config)
96 {
97     CHECK_TRUE(fd != 0, RET_ERR, "NativeMemoryProfilerSaClientManager: fd is 0");
98     CHECK_NOTNULL(config, RET_ERR, "NativeMemoryProfilerSaClientManager: config is nullptr");
99     CHECK_TRUE(CheckConfig(config), RET_ERR, "CheckConfig failed");
100     auto service = GetRemoteService();
101     if (service == nullptr) {
102         PROFILER_LOG_ERROR(LOG_CORE, "NativeMemoryProfilerSaClientManager: stop GetRemoteService failed");
103         return RET_ERR;
104     }
105     NativeMemoryProfilerSaProxy proxy(service);
106     return proxy.DumpData(fd, config);
107 }
108 
GetRemoteService()109 sptr<IRemoteObject> NativeMemoryProfilerSaClientManager::GetRemoteService()
110 {
111     auto abilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
112     if (abilityManager == nullptr) {
113         return nullptr;
114     }
115     return abilityManager->CheckSystemAbility(INativeMemoryProfilerSa::NATIVE_DAEMON_SYSTEM_ABILITY_ID);
116 }
117 
CheckConfig(const std::shared_ptr<NativeMemoryProfilerSaConfig> & config)118 bool NativeMemoryProfilerSaClientManager::CheckConfig(const std::shared_ptr<NativeMemoryProfilerSaConfig>& config)
119 {
120     CHECK_NOTNULL(config, false, "NativeMemoryProfilerSaClientManager: config is nullptr");
121     if (config->duration_ == 0) {
122         PROFILER_LOG_ERROR(LOG_CORE, "NativeMemoryProfilerSaClientManager: duration cannot be 0");
123         return false;
124     }
125     if (config->filePath_.length() >= PATH_MAX) {
126         PROFILER_LOG_ERROR(LOG_CORE, "NativeMemoryProfilerSaClientManager: filePath_ invalid");
127         return false;
128     }
129     if (config->shareMemorySize_ == 0) {
130         config->shareMemorySize_ = config->responseLibraryMode_ ? LIB_SMS : CALL_STACK_SMS;
131     }
132     return true;
133 }
134 
GetMallocStats(int fd,int pid,int type,bool printNmdOnly)135 int32_t NativeMemoryProfilerSaClientManager::GetMallocStats(int fd, int pid, int type, bool printNmdOnly)
136 {
137     CHECK_TRUE(fd != 0, RET_ERR, "NativeMemoryProfilerSaClientManager: GetMallocStats fd is 0");
138     CHECK_TRUE(pid > 0, RET_ERR, "NativeMemoryProfilerSaClientManager: GetMallocStats invalid pid");
139     CHECK_TRUE(type == 0 || type == 1 || type == ONLY_NMD, RET_ERR,
140                "NativeMemoryProfilerSaClientManager: type is invalid");
141     std::shared_ptr<NativeMemoryProfilerSaConfig> config = std::make_shared<NativeMemoryProfilerSaConfig>();
142     config->printNmd_ = true;
143     config->printNmdOnly_ = printNmdOnly;
144     if (config->printNmdOnly_) {
145         config->pid_ = static_cast<int32_t>(pid);
146         config->duration_ = NMD_DURATION;
147         config->mallocDisable_ = true;
148         config->mmapDisable_ = true;
149         config->shareMemorySize_ = NMD_SHMEM;
150     }
151     config->nmdPid_ = static_cast<uint32_t>(pid);
152     config->nmdType_ = static_cast<uint32_t>(type);
153     CHECK_NOTNULL(config, RET_ERR, "NativeMemoryProfilerSaClientManager: config is nullptr");
154     CHECK_TRUE(CheckConfig(config), RET_ERR, "CheckConfig failed");
155     auto service = GetRemoteService();
156     if (service == nullptr) {
157         PROFILER_LOG_ERROR(LOG_CORE, "NativeMemoryProfilerSaClientManager: stop GetRemoteService failed");
158         return RET_ERR;
159     }
160     NativeMemoryProfilerSaProxy proxy(service);
161     return proxy.DumpData(fd, config);
162 }
163 
StartPrintSimplifiedNmd(pid_t pid,std::vector<SimplifiedMemStats> & memStats)164 int32_t NativeMemoryProfilerSaClientManager::StartPrintSimplifiedNmd(pid_t pid,
165                                                                      std::vector<SimplifiedMemStats>& memStats)
166 {
167     CHECK_TRUE(pid > 0, RET_ERR, "NativeMemoryProfilerSaClientManager: StartPrintSimplifiedNmd invalid pid");
168     std::shared_ptr<NativeMemoryProfilerSaConfig> config = std::make_shared<NativeMemoryProfilerSaConfig>();
169     CHECK_NOTNULL(config, RET_ERR, "NativeMemoryProfilerSaClientManager: config is nullptr");
170     config->printNmd_ = true;
171     config->printNmdOnly_ = true;
172     config->pid_ = static_cast<int32_t>(pid);
173     config->duration_ = NMD_DURATION;
174     config->mallocDisable_ = true;
175     config->mmapDisable_ = true;
176     config->shareMemorySize_ = NMD_SHMEM;
177     config->nmdPid_ = static_cast<uint32_t>(pid);
178     config->nmdType_ = static_cast<uint32_t>(SIMP_NMD);
179     CHECK_TRUE(CheckConfig(config), RET_ERR, "CheckConfig failed");
180     auto service = GetRemoteService();
181     if (service == nullptr) {
182         PROFILER_LOG_ERROR(LOG_CORE, "NativeMemoryProfilerSaClientManager: SimplifiedNmd GetRemoteService failed");
183         return RET_ERR;
184     }
185     NativeMemoryProfilerSaProxy proxy(service);
186     std::string replyStats;
187     int32_t ret = proxy.Start(config, replyStats);
188     if (ret != RET_OK) {
189         PROFILER_LOG_ERROR(LOG_CORE, "StartPrintSimplifiedNmd failed");
190         return ret;
191     }
192     size_t newlinePos = replyStats.find_first_of('\n');
193     if (newlinePos != std::string::npos) {
194         replyStats.erase(0, newlinePos + 1);
195     }
196     SimplifiedMemStats tmp;
197     std::istringstream iss(replyStats);
198     std::stringstream ss;
199     std::string line;
200     while (std::getline(iss, line, '\n')) {
201         ss.str("");
202         ss.clear();
203         ss.str(line);
204         ss >> tmp.size >> tmp.allocated >> tmp.nmalloc >> tmp.ndalloc;
205         memStats.push_back(tmp);
206     }
207     return RET_OK;
208 }
209 
Start(int fd,pid_t pid,uint32_t duration,SimplifiedMemConfig & config)210 int32_t NativeMemoryProfilerSaClientManager::Start(int fd, pid_t pid, uint32_t duration, SimplifiedMemConfig& config)
211 {
212     CHECK_TRUE(fd != 0, RET_ERR, "NativeMemoryProfilerSaClientManager: fd is 0");
213     CHECK_TRUE(pid > 0, RET_ERR, "NativeMemoryProfilerSaClientManager: Simplified Start invalid pid");
214     std::shared_ptr<NativeMemoryProfilerSaConfig> nConfig = std::make_shared<NativeMemoryProfilerSaConfig>();
215     CHECK_NOTNULL(nConfig, RET_ERR, "NativeMemoryProfilerSaClientManager: config is nullptr");
216     nConfig->pid_ = static_cast<int32_t>(pid);
217     nConfig->duration_ = duration;
218     nConfig->largestSize_ = config.largestSize;
219     nConfig->secondLargestSize_ = config.secondLargestSize;
220     nConfig->maxGrowthSize_ = config.maxGrowthSize;
221     nConfig->sampleInterval_ = config.sampleSize;
222     nConfig->shareMemorySize_ = CALL_STACK_SMS;
223     nConfig->statisticsInterval_ = FIVE_MINUTES;
224     nConfig->jsStackReport_ = true;
225     nConfig->maxJsStackDepth_ = JS_STACK_DEPS;
226     auto service = GetRemoteService();
227     if (service == nullptr) {
228         PROFILER_LOG_ERROR(LOG_CORE, "NativeMemoryProfilerSaClientManager: Simplified Start GetRemoteService failed");
229         return RET_ERR;
230     }
231     NativeMemoryProfilerSaProxy proxy(service);
232     return proxy.DumpData(fd, nConfig);
233 }
234 } // namespace OHOS::Developtools::NativeDaemon