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