1 /*
2 * Copyright (c) 2023 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 "system_ability_manager_dumper.h"
17
18 #include "accesstoken_kit.h"
19 #include "ffrt_inner.h"
20 #include "file_ex.h"
21 #include "ipc_skeleton.h"
22 #include "system_ability_manager.h"
23 #include "if_local_ability_manager.h"
24 #include "ipc_payload_statistics.h"
25 #include "samgr_err_code.h"
26
27 using namespace std;
28 namespace OHOS {
29 namespace {
30 constexpr const char* HIDUMPER_PROCESS_NAME = "hidumper_service";
31 constexpr const char* ARGS_QUERY_SA = "-sa";
32 constexpr const char* ARGS_QUERY_PROCESS = "-p";
33 constexpr const char* ARGS_QUERY_SA_IN_CURRENT_STATE = "-sm";
34 constexpr const char* ARGS_HELP = "-h";
35 constexpr const char* ARGS_QUERY_ALL = "-l";
36 constexpr const char* ARGS_FFRT_SEPARATOR = "|";
37 constexpr size_t MIN_ARGS_SIZE = 1;
38 constexpr size_t MAX_ARGS_SIZE = 2;
39 constexpr int32_t FFRT_DUMP_PROC_LEN = 2;
40 constexpr int32_t FFRT_DUMP_PIDS_INDEX = 1;
41 constexpr int FFRT_BUFFER_SIZE = 512 * 1024;
42 constexpr int LISTENER_BASE_INDEX = 1;
43 constexpr int32_t FFRT_METRIC_CMD_INDEX = 2;
44 constexpr int32_t FFRT_DUMP_METRIC_LEN = 3;
45 constexpr int32_t COLLECT_FFRT_METRIC_MAX_SIZE = 5000;
46 constexpr int32_t FFRT_STAT_SIZE = sizeof(ffrt_stat);
47 constexpr int32_t BUFFER_SIZE = FFRT_STAT_SIZE * COLLECT_FFRT_METRIC_MAX_SIZE;
48 constexpr int32_t DELAY_TIME = 60 * 1000;
49 constexpr const char* FFRT_STAT_STR_START = "--start-stat";
50 constexpr const char* FFRT_STAT_STR_STOP = "--stop-stat";
51 constexpr const char* FFRT_STAT_STR_GET = "--stat";
52 constexpr const char* IPC_STAT_STR_START = "--start-stat";
53 constexpr const char* IPC_STAT_STR_STOP = "--stop-stat";
54 constexpr const char* IPC_STAT_STR_GET = "--stat";
55 constexpr const char* IPC_STAT_STR_ALL = "all";
56 constexpr const char* IPC_STAT_STR_SAMGR = "samgr";
57 constexpr const char* IPC_DUMP_SUCCESS = " success\n";
58 constexpr const char* IPC_DUMP_FAIL = " fail\n";
59
60 }
61
62 std::shared_ptr<FFRTHandler> SystemAbilityManagerDumper::handler_ = nullptr;
63 char* SystemAbilityManagerDumper::ffrtMetricBuffer = nullptr;
64 bool SystemAbilityManagerDumper::collectEnable = false;
65 samgr::mutex SystemAbilityManagerDumper::ffrtMetricLock;
66
ShowListenerHelp(string & result)67 void SystemAbilityManagerDumper::ShowListenerHelp(string& result)
68 {
69 result.append("SystemAbilityManager Listener Dump options:\n")
70 .append(" [-h] [cmd]...\n")
71 .append("cmd maybe one of:\n")
72 .append(" -sa [said]: query sa listener infos.\n")
73 .append(" -p [pid]: query process listener infos.\n")
74 .append(" -l [-sa | -p]: query all sa listener infos by [sa | process].\n");
75 }
76
ListenerDumpProc(map<int32_t,list<SAListener>> & listeners,int32_t fd,const vector<string> & args)77 int32_t SystemAbilityManagerDumper::ListenerDumpProc(map<int32_t, list<SAListener>>& listeners,
78 int32_t fd, const vector<string>& args)
79 {
80 if (!CanDump()) {
81 HILOGE("Dump failed, not allowed");
82 return ERR_PERMISSION_DENIED;
83 }
84 string result;
85 GetListenerDumpProc(listeners, args, result);
86 return SaveDumpResultToFd(fd, result);
87 }
88
GetListenerDumpProc(map<int32_t,list<SAListener>> & listeners,const vector<string> & args,string & result)89 void SystemAbilityManagerDumper::GetListenerDumpProc(map<int32_t, list<SAListener>>& listeners,
90 const vector<string>& args, string& result)
91 {
92 if (args.size() == MIN_ARGS_SIZE + 1) {
93 // -h
94 if (args[LISTENER_BASE_INDEX] == ARGS_HELP) {
95 ShowListenerHelp(result);
96 return;
97 }
98 } else if (args.size() == MAX_ARGS_SIZE + 1) {
99 // -l
100 if (args[LISTENER_BASE_INDEX] == ARGS_QUERY_ALL) {
101 // -sa
102 if (args[LISTENER_BASE_INDEX + 1] == ARGS_QUERY_SA) {
103 ShowAllBySA(listeners, result);
104 return;
105 }
106 // -p
107 if (args[LISTENER_BASE_INDEX + 1] == ARGS_QUERY_PROCESS) {
108 ShowAllByCallingPid(listeners, result);
109 return;
110 }
111 }
112 // -sa said
113 if (args[LISTENER_BASE_INDEX] == ARGS_QUERY_SA) {
114 int said = atoi(args[LISTENER_BASE_INDEX + 1].c_str());
115 ShowCallingPidBySA(listeners, said, result);
116 return;
117 }
118 // -p pid
119 if (args[LISTENER_BASE_INDEX] == ARGS_QUERY_PROCESS) {
120 int callingPid = atoi(args[LISTENER_BASE_INDEX + 1].c_str());
121 ShowSAByCallingPid(listeners, callingPid, result);
122 return;
123 }
124 }
125 IllegalInput(result);
126 }
127
ShowAllBySA(map<int32_t,list<SAListener>> & listeners,string & result)128 void SystemAbilityManagerDumper::ShowAllBySA(map<int32_t, list<SAListener>>& listeners,
129 string& result)
130 {
131 result += "********************************ShowAllBySA********************************";
132 set<sptr<IRemoteObject>> listenerSet;
133 for (auto iter : listeners) {
134 if (iter.second.size() == 0) {
135 continue;
136 }
137 result += "\n\n--------------------------------SA:";
138 result += to_string(iter.first);
139 result += ", SubCnt:";
140 result += to_string(iter.second.size());
141 result += "--------------------------------";
142 map<int32_t, int32_t> pidCnt;
143 for (auto saListener : iter.second) {
144 pidCnt[saListener.callingPid]++;
145 listenerSet.insert(saListener.listener->AsObject());
146 }
147 for (auto iter : pidCnt) {
148 result += "\ncallingPid:";
149 result += to_string(iter.first);
150 result += ", cnt:";
151 result += to_string(iter.second);
152 }
153 }
154 result += "\n--------------------------------TotalListenerCnt:";
155 result += to_string(listenerSet.size());
156 result += "--------------------------------";
157 result += "\n***************************************************************************\n";
158 }
159
ShowAllByCallingPid(map<int32_t,list<SAListener>> & listeners,string & result)160 void SystemAbilityManagerDumper::ShowAllByCallingPid(map<int32_t, list<SAListener>>& listeners,
161 string& result)
162 {
163 result += "********************************ShowAllByCallingPid********************************";
164 map<int32_t, list<pair<int32_t, sptr<ISystemAbilityStatusChange>>>> subscribeMap;
165 map<int32_t, set<sptr<IRemoteObject>>> pidListenerMap;
166 size_t totalSum = 0;
167 for (auto iter : listeners) {
168 int32_t said = iter.first;
169 for (auto saListener : iter.second) {
170 subscribeMap[saListener.callingPid].push_back({said, saListener.listener});
171 pidListenerMap[saListener.callingPid].insert(saListener.listener->AsObject());
172 }
173 }
174 vector<pair<int32_t, set<sptr<IRemoteObject>>>> vec(pidListenerMap.begin(), pidListenerMap.end());
175 auto cmp = [](const pair<int32_t, set<sptr<IRemoteObject>>>& p1,
176 const pair<int32_t, set<sptr<IRemoteObject>>>& p2) {
177 return p1.second.size() > p2.second.size();
178 };
179 sort(vec.begin(), vec.end(), cmp);
180 for (auto iter : vec) {
181 result += "\n\n--------------------------------CallingPid:";
182 result += to_string(iter.first);
183 result += ", ListenerCnt:";
184 result += to_string(iter.second.size());
185 result += "--------------------------------";
186 totalSum += iter.second.size();
187 map<int32_t, int32_t> saCnt;
188 for (auto p : subscribeMap[iter.first]) {
189 saCnt[p.first]++;
190 }
191 for (auto iter : saCnt) {
192 result += "\nSA:";
193 result += to_string(iter.first);
194 result += ", cnt:";
195 result += to_string(iter.second);
196 }
197 }
198 result += "\n--------------------------------TotalListenerCnt:";
199 result += to_string(totalSum);
200 result += "--------------------------------";
201 result += "\n***********************************************************************************\n";
202 }
203
ShowCallingPidBySA(map<int32_t,list<SAListener>> & listeners,int32_t said,string & result)204 void SystemAbilityManagerDumper::ShowCallingPidBySA(map<int32_t, list<SAListener>>& listeners,
205 int32_t said, string& result)
206 {
207 result += "********************************ShowCallingPidBySA********************************";
208 result += "\n--------------------------------SA:";
209 result += to_string(said);
210 result += "--------------------------------";
211 map<int32_t, int32_t> pidCnt;
212 for (auto iter : listeners) {
213 if (iter.first == said) {
214 for (auto saListener : iter.second) {
215 pidCnt[saListener.callingPid]++;
216 }
217 break;
218 }
219 }
220 int32_t totalSum = 0;
221 for (auto iter : pidCnt) {
222 result += "\ncallingPid:";
223 result += to_string(iter.first);
224 result += ", cnt:";
225 result += to_string(iter.second);
226 totalSum += iter.second;
227 }
228 result += "\n--------------------------------TotalSubCnt:";
229 result += to_string(totalSum);
230 result += "--------------------------------";
231 result += "\n**********************************************************************************\n";
232 }
233
ShowSAByCallingPid(map<int32_t,list<SAListener>> & listeners,int32_t callingPid,string & result)234 void SystemAbilityManagerDumper::ShowSAByCallingPid(map<int32_t, list<SAListener>>& listeners,
235 int32_t callingPid, string& result)
236 {
237 result += "********************************ShowSAByCallingPid********************************";
238 result += "\n--------------------------------CallingPid:";
239 result += to_string(callingPid);
240 result += "--------------------------------";
241 map<int32_t, int32_t> saCnt;
242 set<sptr<IRemoteObject>> listenerSet;
243 for (auto iter : listeners) {
244 int32_t said = iter.first;
245 for (auto saListener : iter.second) {
246 if (saListener.callingPid == callingPid) {
247 saCnt[said]++;
248 listenerSet.insert(saListener.listener->AsObject());
249 }
250 }
251 }
252 for (auto iter : saCnt) {
253 result += "\nSA:";
254 result += to_string(iter.first);
255 result += ", cnt:";
256 result += to_string(iter.second);
257 }
258 result += "\n--------------------------------ListenerCnt:";
259 result += to_string(listenerSet.size());
260 result += "--------------------------------";
261 result += "\n**********************************************************************************\n";
262 }
263
FfrtDumpProc(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,int32_t fd,const std::vector<std::string> & args)264 int32_t SystemAbilityManagerDumper::FfrtDumpProc(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,
265 int32_t fd, const std::vector<std::string>& args)
266 {
267 if (!CanDump()) {
268 HILOGE("Dump failed, not allowed");
269 return ERR_PERMISSION_DENIED;
270 }
271 std::string result;
272 if (args.size() < FFRT_DUMP_PROC_LEN || args[FFRT_DUMP_PIDS_INDEX].empty()) {
273 HILOGE("FfrtDump param pid not exist");
274 IllegalInput(result);
275 return SaveDumpResultToFd(fd, result);
276 }
277 if (args.size() == FFRT_DUMP_PROC_LEN) {
278 GetFfrtDumpInfoProc(abilityStateScheduler, args, result);
279 return SaveDumpResultToFd(fd, result);
280 }
281 if (args.size() == FFRT_DUMP_METRIC_LEN) {
282 GetFfrtLoadMetrics(abilityStateScheduler, fd, args, result);
283 return SaveDumpResultToFd(fd, result);
284 }
285 IllegalInput(result);
286 return SaveDumpResultToFd(fd, result);
287 }
288
GetFfrtLoadMetrics(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,int32_t fd,const std::vector<std::string> & args,std::string & result)289 void SystemAbilityManagerDumper::GetFfrtLoadMetrics(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,
290 int32_t fd, const std::vector<std::string>& args, std::string& result)
291 {
292 std::string pidStr = args[FFRT_DUMP_PIDS_INDEX];
293 std::vector<int32_t> processIds;
294 FfrtDumpParser(processIds, pidStr);
295 if (processIds.empty()) {
296 HILOGE("FfrtDumpParser parse failed, illegal input processIdsStr %{public}s ", pidStr.c_str());
297 IllegalInput(result);
298 return;
299 }
300 int32_t cmd = -1;
301 if (!FfrtStatCmdParser(cmd, args)) {
302 IllegalInput(result);
303 return;
304 }
305 CollectFfrtMetricInfoInProcs(fd, processIds, abilityStateScheduler, cmd, result);
306 }
307
FfrtStatCmdParser(int32_t & cmd,const std::vector<std::string> & args)308 bool SystemAbilityManagerDumper::FfrtStatCmdParser(int32_t& cmd, const std::vector<std::string>& args)
309 {
310 if (args[FFRT_METRIC_CMD_INDEX] == FFRT_STAT_STR_START) {
311 cmd = FFRT_STAT_CMD_START;
312 } else if (args[FFRT_METRIC_CMD_INDEX] == FFRT_STAT_STR_STOP) {
313 cmd = FFRT_STAT_CMD_STOP;
314 } else if (args[FFRT_METRIC_CMD_INDEX] == FFRT_STAT_STR_GET) {
315 cmd = FFRT_STAT_CMD_GET;
316 } else {
317 return false;
318 }
319 return true;
320 }
321
CollectFfrtMetricInfoInProcs(int32_t fd,const std::vector<int32_t> & processIds,std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,int32_t cmd,std::string & result)322 void SystemAbilityManagerDumper::CollectFfrtMetricInfoInProcs(int32_t fd, const std::vector<int32_t>& processIds,
323 std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, int32_t cmd, std::string& result)
324 {
325 for (const int32_t pid : processIds) {
326 if (pid == getpid()) {
327 CollectFfrtStatistics(cmd, result);
328 continue;
329 }
330 sptr<ILocalAbilityManager> obj = GetProcByProcessId(abilityStateScheduler, pid);
331 if (obj == nullptr) {
332 HILOGE("CollectFfrtMetricInfoInProcs GetSystemProcess failed");
333 result.append("process " + std::to_string(pid) + " not found!\n");
334 continue;
335 }
336 obj->FfrtStatCmdProc(fd, cmd);
337 }
338 }
339
StartFfrtStatistics(std::string & result)340 bool SystemAbilityManagerDumper::StartFfrtStatistics(std::string& result)
341 {
342 if (collectEnable) {
343 result.append("collect has been started\n");
344 return false;
345 }
346 ClearFfrtStatisticsBufferLocked();
347 ffrtMetricBuffer = new char[BUFFER_SIZE]();
348 auto ret = ffrt_dump(ffrt_dump_cmd_t::DUMP_START_STAT, ffrtMetricBuffer, BUFFER_SIZE);
349 if (ret != ERR_OK) {
350 ClearFfrtStatisticsBufferLocked();
351 result.append("collect start failed\n");
352 return false;
353 }
354 collectEnable = true;
355 result.append("collect start success\n");
356 if (handler_ == nullptr) {
357 handler_ = std::make_shared<FFRTHandler>("ffrtDumpHandler");
358 }
359 HILOGI("StartFfrtStatistics PostTask delayTime:%{public}dms", DELAY_TIME);
360 handler_->PostTask(ClearFfrtStatistics, "ClearFfrtStatistics", DELAY_TIME);
361 return true;
362 }
363
StopFfrtStatistics(std::string & result)364 bool SystemAbilityManagerDumper::StopFfrtStatistics(std::string& result)
365 {
366 if (!collectEnable) {
367 result.append("collect has not been started\n");
368 return false;
369 }
370 collectEnable = false;
371 auto ret = ffrt_dump(ffrt_dump_cmd_t::DUMP_STOP_STAT, ffrtMetricBuffer, BUFFER_SIZE);
372 if (ret != ERR_OK) {
373 ClearFfrtStatisticsBufferLocked();
374 result.append("collect stop failed\n");
375 return false;
376 }
377 result.append("collect stop success\n");
378 return true;
379 }
380
GetFfrtStatistics(std::string & result)381 bool SystemAbilityManagerDumper::GetFfrtStatistics(std::string& result)
382 {
383 if (collectEnable) {
384 result.append("collect has not been stopped\n");
385 return false;
386 }
387 if (ffrtMetricBuffer == nullptr) {
388 result.append("info not collected\n");
389 return false;
390 }
391 FfrtStatisticsParser(result);
392 ClearFfrtStatisticsBufferLocked();
393 handler_ = nullptr;
394 return true;
395 }
396
FfrtStatisticsParser(std::string & result)397 void SystemAbilityManagerDumper::FfrtStatisticsParser(std::string& result)
398 {
399 ffrt_stat* currentStat = (ffrt_stat*)ffrtMetricBuffer;
400 char* lastStat = ffrtMetricBuffer + BUFFER_SIZE;
401 std::string taskInfo;
402 uint64_t maxTime = 0;
403 uint64_t minTime = std::numeric_limits<uint64_t>::max();
404 uint64_t sumTime = 0;
405 uint64_t avgTime = 0;
406 uint64_t count = 0;
407 while ((char*)currentStat < lastStat && std::strcmp(currentStat->taskName, "") != 0) {
408 if (currentStat->startTime > currentStat->endTime) {
409 currentStat = (ffrt_stat*)((char*)currentStat + FFRT_STAT_SIZE);
410 continue;
411 }
412 auto duration = currentStat->endTime - currentStat->startTime;
413 sumTime += duration;
414 maxTime = std::max(maxTime, duration);
415 minTime = std::min(minTime, duration);
416 ++count;
417 taskInfo.append(currentStat->taskName);
418 taskInfo.append(" " + ToString(currentStat->startTime));
419 taskInfo.append(" " + ToString(currentStat->endTime) + "\n");
420 currentStat = (ffrt_stat*)((char*)currentStat + FFRT_STAT_SIZE);
421 }
422 if (count == 0) {
423 minTime = 0;
424 } else {
425 avgTime = sumTime / count;
426 }
427 result.append("sumTime:" + ToString(sumTime) + " maxTime:" + ToString(maxTime));
428 result.append(" minTime:" + ToString(minTime) + " avgTime:" + ToString(avgTime));
429 result.append(" cntTime:" + ToString(count) + "\n");
430 result.append("-------------------------------------------------------------------------------------------\n");
431 result.append("taskName startTime(us) endTime(us)\n");
432 result.append("-------------------------------------------------------------------------------------------\n");
433 result.append(taskInfo);
434 result.append("-------------------------------------------------------------------------------------------\n");
435 }
436
ClearFfrtStatisticsBufferLocked()437 void SystemAbilityManagerDumper::ClearFfrtStatisticsBufferLocked()
438 {
439 if (ffrtMetricBuffer != nullptr) {
440 delete[] ffrtMetricBuffer;
441 ffrtMetricBuffer = nullptr;
442 HILOGI("ClearFfrtStatisticsBuffer success");
443 }
444 if (handler_ != nullptr) {
445 handler_->RemoveTask("ClearFfrtStatistics");
446 }
447 }
448
ClearFfrtStatistics()449 void SystemAbilityManagerDumper::ClearFfrtStatistics()
450 {
451 HILOGW("ClearFfrtStatistics start");
452 std::lock_guard<samgr::mutex> autoLock(ffrtMetricLock);
453 if (collectEnable) {
454 auto ret = ffrt_dump(ffrt_dump_cmd_t::DUMP_STOP_STAT, ffrtMetricBuffer, BUFFER_SIZE);
455 if (ret != ERR_OK) {
456 HILOGE("ClearFfrtStatistics stop ffrt_dump err:%{public}d", ret);
457 }
458 collectEnable = false;
459 }
460 ClearFfrtStatisticsBufferLocked();
461 }
462
CollectFfrtStatistics(int32_t cmd,std::string & result)463 bool SystemAbilityManagerDumper::CollectFfrtStatistics(int32_t cmd, std::string& result)
464 {
465 std::lock_guard<samgr::mutex> autoLock(ffrtMetricLock);
466 result.append("pid:" + ToString(getpid()) + " ");
467 auto ret = false;
468 switch (cmd) {
469 case FFRT_STAT_CMD_START: {
470 ret = StartFfrtStatistics(result);
471 break;
472 }
473 case FFRT_STAT_CMD_STOP: {
474 ret = StopFfrtStatistics(result);
475 break;
476 }
477 case FFRT_STAT_CMD_GET: {
478 ret = GetFfrtStatistics(result);
479 break;
480 }
481 default:
482 break;
483 }
484 return ret;
485 }
486
GetProcByProcessId(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,int32_t processId)487 sptr<ILocalAbilityManager> SystemAbilityManagerDumper::GetProcByProcessId(
488 std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, int32_t processId)
489 {
490 std::u16string processName;
491 int32_t queryResult = abilityStateScheduler->GetProcessNameByProcessId(processId, processName);
492 if (queryResult != ERR_OK) {
493 HILOGE("GetProcessNameByProcessId failed, pid %{public}d not exist", processId);
494 return nullptr;
495 }
496 sptr<ILocalAbilityManager> obj =
497 iface_cast<ILocalAbilityManager>(SystemAbilityManager::GetInstance()->GetSystemProcess(processName));
498 if (obj == nullptr) {
499 HILOGE("GetSystemProcess failed, pid:%{public}d processName:%{public}s not exist",
500 processId, Str16ToStr8(processName).c_str());
501 }
502 return obj;
503 }
504
GetFfrtDumpInfoProc(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,const std::vector<std::string> & args,std::string & result)505 bool SystemAbilityManagerDumper::GetFfrtDumpInfoProc(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,
506 const std::vector<std::string>& args, std::string& result)
507 {
508 std::string pidStr = args[FFRT_DUMP_PIDS_INDEX];
509 std::vector<int32_t> processIds;
510 FfrtDumpParser(processIds, pidStr);
511 if (processIds.empty()) {
512 HILOGE("FfrtDumpParser parse failed, illegal input processIdsStr %{public}s ", pidStr.c_str());
513 IllegalInput(result);
514 return false;
515 }
516 HILOGD("FfrtDumpProc: processIdsSize=%{public}zu", processIds.size());
517 for (const int32_t pid : processIds) {
518 if (pid == getpid()) {
519 GetSAMgrFfrtInfo(result);
520 continue;
521 }
522 DumpFfrtInfoInProc(abilityStateScheduler, pid, result);
523 }
524 return true;
525 }
526
FfrtDumpParser(std::vector<int32_t> & processIds,const std::string & processIdsStr)527 bool SystemAbilityManagerDumper::FfrtDumpParser(std::vector<int32_t>& processIds, const std::string& processIdsStr)
528 {
529 std::string processIdsVecStr = processIdsStr + ARGS_FFRT_SEPARATOR;
530 std::size_t pos = processIdsVecStr.find(ARGS_FFRT_SEPARATOR);
531 while (pos != std::string::npos) {
532 std::string processIdStr = processIdsVecStr.substr(0, pos);
533 processIdsVecStr = processIdsVecStr.substr(pos + 1, processIdsVecStr.size() - pos - 1);
534 pos = processIdsVecStr.find(ARGS_FFRT_SEPARATOR);
535 int32_t processId = -1;
536 if (!StrToInt(processIdStr, processId)) {
537 HILOGE("StrToInt processIdStr %{public}s error", processIdStr.c_str());
538 continue;
539 }
540 if (processId > 0) {
541 processIds.emplace_back(processId);
542 }
543 }
544 return true;
545 }
546
GetSAMgrFfrtInfo(std::string & result)547 void SystemAbilityManagerDumper::GetSAMgrFfrtInfo(std::string& result)
548 {
549 char* buffer = new char[FFRT_BUFFER_SIZE + 1]();
550 buffer[FFRT_BUFFER_SIZE] = 0;
551 ffrt_dump(ffrt_dump_cmd_t::DUMP_INFO_ALL, buffer, FFRT_BUFFER_SIZE);
552 if (strlen(buffer) == 0) {
553 HILOGE("get samgr FfrtDumperInfo failed");
554 delete[] buffer;
555 return;
556 }
557 std::string ffrtDumpInfoStr(buffer);
558 result.append(ffrtDumpInfoStr + "\n");
559 delete[] buffer;
560 }
561
DumpFfrtInfoInProc(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,int32_t pid,std::string & result)562 void SystemAbilityManagerDumper::DumpFfrtInfoInProc(
563 std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, int32_t pid, std::string& result)
564 {
565 sptr<ILocalAbilityManager> obj = GetProcByProcessId(abilityStateScheduler, pid);
566 if (obj == nullptr) {
567 HILOGE("DumpFfrtInfoInProc GetSystemProcess failed");
568 result.append("process " + std::to_string(pid) + " not found!\n");
569 return;
570 }
571 std::string resultForProcess;
572 if (!obj->FfrtDumperProc(resultForProcess)) {
573 HILOGE("safwk FfrtDumperProc execute failed");
574 return;
575 }
576 result.append(resultForProcess + "\n");
577 }
578
SaveDumpResultToFd(int32_t fd,const std::string & result)579 int32_t SystemAbilityManagerDumper::SaveDumpResultToFd(int32_t fd, const std::string& result)
580 {
581 if (!SaveStringToFd(fd, result)) {
582 HILOGE("save to fd failed");
583 return SAVE_FD_FAIL;
584 }
585 HILOGD("save to fd success");
586 return ERR_OK;
587 }
588
StartSamgrIpcStatistics(std::string & result)589 bool SystemAbilityManagerDumper::StartSamgrIpcStatistics(std::string& result)
590 {
591 result = std::string("StartIpcStatistics pid:") + std::to_string(getpid());
592 bool ret = IPCPayloadStatistics::StartStatistics();
593 result += ret ? IPC_DUMP_SUCCESS : IPC_DUMP_FAIL;
594 return ret;
595 }
596
StopSamgrIpcStatistics(std::string & result)597 bool SystemAbilityManagerDumper::StopSamgrIpcStatistics(std::string& result)
598 {
599 result = std::string("StopSamgrIpcStatistics pid:") + std::to_string(getpid());
600 bool ret = IPCPayloadStatistics::StopStatistics();
601 result += ret ? IPC_DUMP_SUCCESS : IPC_DUMP_FAIL;
602 return ret;
603 }
604
GetSamgrIpcStatistics(std::string & result)605 bool SystemAbilityManagerDumper::GetSamgrIpcStatistics(std::string& result)
606 {
607 result += "********************************GlobalStatisticsInfo********************************";
608 result += "\nCurrentPid:";
609 result += std::to_string(getpid());
610 result += "\nTotalCount:";
611 result += std::to_string(IPCPayloadStatistics::GetTotalCount());
612 result += "\nTotalTimeCost:";
613 result += std::to_string(IPCPayloadStatistics::GetTotalCost());
614 std::vector<int32_t> pids;
615 pids = IPCPayloadStatistics::GetPids();
616 for (unsigned int i = 0; i < pids.size(); i++) {
617 result += "\n--------------------------------ProcessStatisticsInfo-------------------------------";
618 result += "\nCallingPid:";
619 result += std::to_string(pids[i]);
620 result += "\nCallingPidTotalCount:";
621 result += std::to_string(IPCPayloadStatistics::GetCount(pids[i]));
622 result += "\nCallingPidTotalTimeCost:";
623 result += std::to_string(IPCPayloadStatistics::GetCost(pids[i]));
624 std::vector<IPCInterfaceInfo> intfs;
625 intfs = IPCPayloadStatistics::GetDescriptorCodes(pids[i]);
626 for (unsigned int j = 0; j < intfs.size(); j++) {
627 result += "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~InterfaceStatisticsInfo~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
628 result += "\nDescriptorCode:";
629 result += Str16ToStr8(intfs[j].desc) + std::string("_") + std::to_string(intfs[j].code);
630 result += "\nDescriptorCodeCount:";
631 result += std::to_string(
632 IPCPayloadStatistics::GetDescriptorCodeCount(pids[i], intfs[j].desc, intfs[j].code));
633 result += "\nDescriptorCodeTimeCost:";
634 result += "\nTotal:";
635 result += std::to_string(
636 IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).totalCost);
637 result += " | Max:";
638 result += std::to_string(
639 IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).maxCost);
640 result += " | Min:";
641 result += std::to_string(
642 IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).minCost);
643 result += " | Avg:";
644 result += std::to_string(
645 IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).averCost);
646 result += "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
647 }
648 result += "\n------------------------------------------------------------------------------------";
649 }
650 result += "\n************************************************************************************\n";
651 return true;
652 }
653
IpcDumpIsAllProcess(const std::string & processName)654 bool SystemAbilityManagerDumper::IpcDumpIsAllProcess(const std::string& processName)
655 {
656 return processName == IPC_STAT_STR_ALL;
657 }
658
IpcDumpIsSamgr(const std::string & processName)659 bool SystemAbilityManagerDumper::IpcDumpIsSamgr(const std::string& processName)
660 {
661 return processName == IPC_STAT_STR_SAMGR;
662 }
663
IpcDumpCmdParser(int32_t & cmd,const std::vector<std::string> & args)664 bool SystemAbilityManagerDumper::IpcDumpCmdParser(int32_t& cmd, const std::vector<std::string>& args)
665 {
666 if (!CanDump()) {
667 HILOGE("IPC Dump failed, not allowed");
668 return false;
669 }
670
671 if (args.size() < IPC_STAT_CMD_LEN) {
672 HILOGE("IPC Dump failed, length error");
673 return false;
674 }
675
676 if (args[IPC_STAT_CMD_INDEX] == IPC_STAT_STR_START) {
677 cmd = IPC_STAT_CMD_START;
678 } else if (args[IPC_STAT_CMD_INDEX] == IPC_STAT_STR_STOP) {
679 cmd = IPC_STAT_CMD_STOP;
680 } else if (args[IPC_STAT_CMD_INDEX] == IPC_STAT_STR_GET) {
681 cmd = IPC_STAT_CMD_GET;
682 } else {
683 return false;
684 }
685 return true;
686 }
687
Dump(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,const std::vector<std::string> & args,std::string & result)688 bool SystemAbilityManagerDumper::Dump(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,
689 const std::vector<std::string>& args, std::string& result)
690 {
691 if (!CanDump()) {
692 HILOGE("Dump failed, not allowed");
693 return false;
694 }
695 if (args.size() == MIN_ARGS_SIZE) {
696 // -l
697 if (args[0] == ARGS_QUERY_ALL) {
698 ShowAllSystemAbilityInfo(abilityStateScheduler, result);
699 return true;
700 }
701 // -h
702 if (args[0] == ARGS_HELP) {
703 ShowHelp(result);
704 return true;
705 }
706 }
707 if (args.size() == MAX_ARGS_SIZE) {
708 // -sa said
709 if (args[0] == ARGS_QUERY_SA) {
710 int said = atoi(args[1].c_str());
711 ShowSystemAbilityInfo(said, abilityStateScheduler, result);
712 return true;
713 }
714 // -p processname
715 if (args[0] == ARGS_QUERY_PROCESS) {
716 ShowProcessInfo(args[1], abilityStateScheduler, result);
717 return true;
718 }
719 // -sm state
720 if (args[0] == ARGS_QUERY_SA_IN_CURRENT_STATE) {
721 ShowAllSystemAbilityInfoInState(args[1], abilityStateScheduler, result);
722 return true;
723 }
724 }
725 IllegalInput(result);
726 return false;
727 }
728
CanDump()729 bool SystemAbilityManagerDumper::CanDump()
730 {
731 uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
732 Security::AccessToken::NativeTokenInfo nativeTokenInfo;
733 int32_t result = Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(accessToken, nativeTokenInfo);
734 if (result == ERR_OK && nativeTokenInfo.processName == HIDUMPER_PROCESS_NAME) {
735 return true;
736 }
737 return false;
738 }
739
ShowHelp(std::string & result)740 void SystemAbilityManagerDumper::ShowHelp(std::string& result)
741 {
742 result.append("SystemAbilityManager Dump options:\n")
743 .append(" [-h] [cmd]...\n")
744 .append("cmd maybe one of:\n")
745 .append(" -sa said: query sa state infos.\n")
746 .append(" -p processname: query process state infos.\n")
747 .append(" -sm state: query all sa based on state infos.\n")
748 .append(" -l: query all sa state infos.\n")
749 .append(" --listener -h: help text for listener.\n")
750 .append(" --ffrt [pid1|pid2] --start-stat/--stop-stat/--stat: start/stop/get")
751 .append(" the FFRT load statistics of a process.\n")
752 .append(" --ffrt [pid1|pid2]: query the FFRT dump infos of a process.\n")
753 .append(" --ipc procname/all --start-stat/--stop-stat/--stat: start/stop/get")
754 .append(" the IPC load statistics of a process.\n");
755 }
756
ShowAllSystemAbilityInfo(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,std::string & result)757 void SystemAbilityManagerDumper::ShowAllSystemAbilityInfo(
758 std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, std::string& result)
759 {
760 if (abilityStateScheduler == nullptr) {
761 HILOGE("abilityStateScheduler is nullptr");
762 return;
763 }
764 abilityStateScheduler->GetAllSystemAbilityInfo(result);
765 }
766
ShowSystemAbilityInfo(int32_t said,std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,std::string & result)767 void SystemAbilityManagerDumper::ShowSystemAbilityInfo(int32_t said,
768 std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, std::string& result)
769 {
770 if (abilityStateScheduler == nullptr) {
771 HILOGE("abilityStateScheduler is nullptr");
772 return;
773 }
774 abilityStateScheduler->GetSystemAbilityInfo(said, result);
775 }
776
ShowProcessInfo(const std::string & processName,std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,std::string & result)777 void SystemAbilityManagerDumper::ShowProcessInfo(const std::string& processName,
778 std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, std::string& result)
779 {
780 if (abilityStateScheduler == nullptr) {
781 HILOGE("abilityStateScheduler is nullptr");
782 return;
783 }
784 abilityStateScheduler->GetProcessInfo(processName, result);
785 }
786
ShowAllSystemAbilityInfoInState(const std::string & state,std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,std::string & result)787 void SystemAbilityManagerDumper::ShowAllSystemAbilityInfoInState(const std::string& state,
788 std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, std::string& result)
789 {
790 if (abilityStateScheduler == nullptr) {
791 HILOGE("abilityStateScheduler is nullptr");
792 return;
793 }
794 abilityStateScheduler->GetAllSystemAbilityInfoByState(state, result);
795 }
796
IllegalInput(std::string & result)797 void SystemAbilityManagerDumper::IllegalInput(std::string& result)
798 {
799 result.append("The arguments are illegal and you can enter '-h' for help.\n");
800 }
801 } // namespace OHOS