• 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 }
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