1 /*
2 * Copyright (C) 2021 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 "util/config_utils.h"
16 #include "directory_ex.h"
17 #include "hilog_wrapper.h"
18 #include "dump_common_utils.h"
19 #include "dump_utils.h"
20 #include "parameter.h"
21 #include "common/dumper_constant.h"
22 namespace OHOS {
23 namespace HiviewDFX {
24 namespace {
25 constexpr int ROOT_UID = 0;
26 constexpr int APP_FIRST_UID = 10000;
27 static const std::string SMAPS_PATH = "smaps/";
28 static const std::string SMAPS_PATH_START = "/proc/";
29 static const std::string SMAPS_PATH_END = "/smaps";
30 } // namespace
31
ConfigUtils(const std::shared_ptr<DumperParameter> & param)32 ConfigUtils::ConfigUtils(const std::shared_ptr<DumperParameter> ¶m) : dumperParam_(param)
33 {
34 }
35
~ConfigUtils()36 ConfigUtils::~ConfigUtils()
37 {
38 pidInfos_.clear();
39 cpuInfos_.clear();
40 currentPidInfos_.clear();
41 currentPidInfo_.Reset();
42 }
43
GetDumperConfigs(const std::shared_ptr<DumperParameter> & param)44 DumpStatus ConfigUtils::GetDumperConfigs(const std::shared_ptr<DumperParameter> ¶m)
45 {
46 DUMPER_HILOGD(MODULE_COMMON, "enter|");
47 DumpStatus ret = DumpStatus::DUMP_FAIL;
48
49 if (param != nullptr) {
50 ConfigUtils configUtils(param);
51 ret = configUtils.GetDumperConfigs();
52 }
53
54 if (ret == DumpStatus::DUMP_OK) {
55 auto dumpCfgs = param->GetExecutorConfigList();
56 for (size_t i = 0; i < dumpCfgs.size(); i++) {
57 dumpCfgs[i]->Dump();
58 }
59 }
60
61 DUMPER_HILOGD(MODULE_COMMON, "leave|ret=%{public}d", ret);
62 return ret;
63 }
64
GetDumperConfigs()65 DumpStatus ConfigUtils::GetDumperConfigs()
66 {
67 DUMPER_HILOGD(MODULE_COMMON, "enter|");
68
69 DumpCommonUtils::GetPidInfos(pidInfos_);
70 DumpCommonUtils::GetCpuInfos(cpuInfos_);
71 DUMPER_HILOGD(MODULE_COMMON, "debug|pidInfos=%{public}zu, cpuInfos=%{public}zu",
72 pidInfos_.size(), cpuInfos_.size());
73
74 std::vector<std::shared_ptr<DumpCfg>> dumpCfgs;
75
76 currentPidInfo_.Reset();
77 currentPidInfos_.clear();
78
79 HandleDumpCpuFreq(dumpCfgs); // cpuid
80 HandleDumpCpuUsage(dumpCfgs); // pid
81 HandleDumpLog(dumpCfgs);
82 HandleDumpMem(dumpCfgs);
83 HandleDumpStorage(dumpCfgs);
84 HandleDumpNet(dumpCfgs);
85 HandleDumpList(dumpCfgs);
86 HandleDumpAbility(dumpCfgs);
87 HandleDumpService(dumpCfgs);
88 HandleDumpSystem(dumpCfgs);
89 HandleDumpProcesses(dumpCfgs);
90 HandleDumpFaultLog(dumpCfgs);
91 HandleDumpAppendix(dumpCfgs);
92 HandleDumpTest(dumpCfgs);
93
94 DUMPER_HILOGD(MODULE_COMMON, "debug|dumpCfgs=%{public}zu", dumpCfgs.size());
95
96 dumperParam_->SetExecutorConfigList(dumpCfgs);
97
98 DUMPER_HILOGD(MODULE_COMMON, "leave|");
99 return DumpStatus::DUMP_OK;
100 }
101
GetSectionNames(const std::string & name,std::vector<std::string> & nameList)102 DumpStatus ConfigUtils::GetSectionNames(const std::string &name, std::vector<std::string> &nameList)
103 {
104 std::vector<std::string> tmpUse;
105 GetGroupNames(name, tmpUse);
106 std::transform(tmpUse.begin(), tmpUse.end(), std::back_inserter(nameList),
107 [](std::string &a) { return GetSectionName(a); });
108 DumpUtils::RemoveDuplicateString(nameList); // remove duplicate log names
109 return DumpStatus::DUMP_OK;
110 }
111
GetGroupNames(const std::string & name,std::vector<std::string> & nameList)112 DumpStatus ConfigUtils::GetGroupNames(const std::string &name, std::vector<std::string> &nameList)
113 {
114 bool check = !name.empty();
115 for (int i = 0; i < groupSum_; i++) {
116 if (groups_[i].name_.empty()) {
117 continue;
118 }
119 if (check && (groups_[i].name_.find(name) != 0)) {
120 continue;
121 }
122 nameList.push_back(groups_[i].name_);
123 }
124 return DumpStatus::DUMP_OK;
125 }
126
GetSectionName(const std::string & name)127 std::string ConfigUtils::GetSectionName(const std::string &name)
128 {
129 std::string ret;
130 std::size_t pos = name.find_last_of(CONFIG_NAME_SPLIT);
131 if (pos != std::string::npos) {
132 ret = name.substr(pos + 1);
133 }
134 return ret;
135 }
136
MergePidInfos(std::vector<DumpCommonUtils::PidInfo> & pidInfos,int pid)137 bool ConfigUtils::MergePidInfos(std::vector<DumpCommonUtils::PidInfo> &pidInfos, int pid)
138 {
139 pidInfos.clear();
140 if (pid < 0) {
141 currentPidInfo_.pid_ = pid;
142 currentPidInfo_.uid_ = -1;
143 pidInfos.assign(pidInfos_.begin(), pidInfos_.end());
144 } else {
145 if (DumpCommonUtils::GetProcessInfo(pid, currentPidInfo_)) {
146 pidInfos.push_back(currentPidInfo_);
147 }
148 }
149 return true;
150 }
151
HandleDumpLog(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)152 bool ConfigUtils::HandleDumpLog(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
153 {
154 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
155 if (!dumperOpts.isDumpLog_) {
156 return false;
157 }
158
159 DUMPER_HILOGD(MODULE_COMMON, "debug|log");
160 currentPidInfo_.Reset();
161 currentPidInfos_.clear();
162
163 auto args = OptionArgs::Create();
164 args->SetStrList(dumperOpts.logArgs_);
165 for (size_t i = 0; i < dumperOpts.logArgs_.size(); i++) {
166 std::string name = CONFIG_GROUP_LOG_ + dumperOpts.logArgs_[i];
167 GetConfig(name, dumpCfgs, args);
168 }
169
170 currentPidInfos_.clear();
171 currentPidInfo_.Reset();
172 return true;
173 }
174
HandleDumpList(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)175 bool ConfigUtils::HandleDumpList(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
176 {
177 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
178 if (!dumperOpts.isDumpList_) {
179 return false;
180 }
181
182 DUMPER_HILOGD(MODULE_COMMON, "debug|list");
183 currentPidInfo_.Reset();
184 currentPidInfos_.clear();
185
186 if (dumperOpts.isDumpSystemAbility_) {
187 DUMPER_HILOGD(MODULE_COMMON, "debug|list ability");
188 std::shared_ptr<OptionArgs> args;
189 GetConfig(CONFIG_DUMPER_LIST_SYSTEM_ABILITY, dumpCfgs, args);
190 }
191
192 if (dumperOpts.isDumpService_) {
193 DUMPER_HILOGD(MODULE_COMMON, "debug|list service");
194 std::shared_ptr<OptionArgs> args;
195 GetConfig(CONFIG_DUMPER_LIST_SERVICE, dumpCfgs, args);
196 }
197
198 if (dumperOpts.isDumpSystem_) {
199 DUMPER_HILOGD(MODULE_COMMON, "debug|list system");
200 std::shared_ptr<OptionArgs> args;
201 GetConfig(CONFIG_DUMPER_LIST_SYSTEM, dumpCfgs, args);
202 }
203
204 currentPidInfos_.clear();
205 currentPidInfo_.Reset();
206 return true;
207 }
208
HandleDumpService(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)209 bool ConfigUtils::HandleDumpService(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
210 {
211 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
212 if (dumperOpts.isDumpList_ || (!dumperOpts.isDumpService_)) {
213 return false;
214 }
215
216 DUMPER_HILOGD(MODULE_COMMON, "debug|service");
217 currentPidInfo_.Reset();
218 currentPidInfos_.clear();
219
220 std::shared_ptr<OptionArgs> args;
221 GetConfig(CONFIG_GROUP_SERVICE, dumpCfgs, args);
222
223 currentPidInfos_.clear();
224 currentPidInfo_.Reset();
225 return true;
226 }
227
HandleDumpAbility(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)228 bool ConfigUtils::HandleDumpAbility(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
229 {
230 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
231 if (dumperOpts.isDumpList_ || (!dumperOpts.isDumpSystemAbility_)) {
232 return false;
233 }
234
235 DUMPER_HILOGD(MODULE_COMMON, "debug|ability");
236 currentPidInfo_.Reset();
237 currentPidInfos_.clear();
238
239 auto args = OptionArgs::Create();
240 args->SetNamesAndArgs(dumperOpts.abilitieNames_, dumperOpts.abilitieArgs_);
241 GetConfig(CONFIG_GROUP_ABILITY, dumpCfgs, args);
242
243 currentPidInfos_.clear();
244 currentPidInfo_.Reset();
245 return true;
246 }
247
HandleDumpSystem(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)248 bool ConfigUtils::HandleDumpSystem(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
249 {
250 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
251 if (dumperOpts.isDumpList_ || (!dumperOpts.isDumpSystem_)) {
252 return false;
253 }
254
255 DUMPER_HILOGD(MODULE_COMMON, "debug|system");
256 currentPidInfo_.Reset();
257 currentPidInfos_.clear();
258
259 if (dumperOpts.systemArgs_.empty()) {
260 std::shared_ptr<OptionArgs> args;
261 GetConfig(CONFIG_GROUP_SYSTEM_BASE, dumpCfgs, args);
262 GetConfig(CONFIG_GROUP_SYSTEM_SYSTEM, dumpCfgs, args);
263 return true;
264 }
265
266 auto args = OptionArgs::Create();
267 args->SetStrList(dumperOpts.systemArgs_);
268 for (size_t i = 0; i < dumperOpts.systemArgs_.size(); i++) {
269 std::string name = CONFIG_GROUP_SYSTEM_ + dumperOpts.systemArgs_[i];
270 GetConfig(name, dumpCfgs, args);
271 }
272
273 currentPidInfos_.clear();
274 currentPidInfo_.Reset();
275 return true;
276 }
277
HandleDumpCpuFreq(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)278 bool ConfigUtils::HandleDumpCpuFreq(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
279 {
280 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
281 if (!dumperOpts.isDumpCpuFreq_) {
282 return false;
283 }
284
285 DUMPER_HILOGD(MODULE_COMMON, "debug|cpu freq");
286 currentPidInfo_.Reset();
287 currentPidInfos_.clear();
288
289 std::shared_ptr<OptionArgs> args;
290 GetConfig(CONFIG_GROUP_CPU_FREQ, dumpCfgs, args);
291
292 currentPidInfos_.clear();
293 currentPidInfo_.Reset();
294 return true;
295 }
296
HandleDumpCpuUsage(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)297 bool ConfigUtils::HandleDumpCpuUsage(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
298 {
299 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
300 if (!dumperOpts.isDumpCpuUsage_) {
301 return false;
302 }
303
304 DUMPER_HILOGD(MODULE_COMMON, "debug|cpu usage");
305 currentPidInfo_.Reset();
306 currentPidInfos_.clear();
307 MergePidInfos(currentPidInfos_, dumperOpts.cpuUsagePid_);
308
309 std::shared_ptr<OptionArgs> args;
310 GetConfig(CONFIG_GROUP_CPU_USAGE, dumpCfgs, args);
311
312 currentPidInfos_.clear();
313 currentPidInfo_.Reset();
314 return true;
315 }
316
HandleDumpMem(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)317 bool ConfigUtils::HandleDumpMem(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
318 {
319 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
320 if (!dumperOpts.isDumpMem_) {
321 return false;
322 }
323
324 DUMPER_HILOGD(MODULE_COMMON, "debug|mem");
325 currentPidInfo_.Reset();
326 currentPidInfos_.clear();
327 MergePidInfos(currentPidInfos_, dumperOpts.memPid_);
328
329 std::shared_ptr<OptionArgs> args;
330 GetConfig(CONFIG_GROUP_MEMORY, dumpCfgs, args);
331
332 currentPidInfos_.clear();
333 currentPidInfo_.Reset();
334 return true;
335 }
336
HandleDumpStorage(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)337 bool ConfigUtils::HandleDumpStorage(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
338 {
339 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
340 if (!dumperOpts.isDumpStorage_) {
341 return false;
342 }
343
344 DUMPER_HILOGD(MODULE_COMMON, "debug|storage");
345 currentPidInfo_.Reset();
346 currentPidInfos_.clear();
347
348 std::shared_ptr<OptionArgs> args;
349 GetConfig(CONFIG_GROUP_STORAGE, dumpCfgs, args);
350
351 currentPidInfos_.clear();
352 currentPidInfo_.Reset();
353 return true;
354 }
355
HandleDumpNet(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)356 bool ConfigUtils::HandleDumpNet(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
357 {
358 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
359 if (!dumperOpts.isDumpNet_) {
360 return false;
361 }
362
363 DUMPER_HILOGD(MODULE_COMMON, "debug|net");
364 currentPidInfo_.Reset();
365 currentPidInfos_.clear();
366
367 std::shared_ptr<OptionArgs> args;
368 GetConfig(CONFIG_GROUP_NET, dumpCfgs, args);
369
370 currentPidInfos_.clear();
371 currentPidInfo_.Reset();
372 return true;
373 }
374
HandleDumpProcesses(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)375 bool ConfigUtils::HandleDumpProcesses(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
376 {
377 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
378 std::string path = dumperOpts.path_;
379 if (!dumperOpts.isDumpProcesses_) {
380 return false;
381 }
382
383 DUMPER_HILOGD(MODULE_COMMON, "debug|processes");
384 currentPidInfo_.Reset();
385 currentPidInfos_.clear();
386 MergePidInfos(currentPidInfos_, dumperOpts.processPid_);
387
388 std::string mode = GetBuildType();
389 std::shared_ptr<OptionArgs> args;
390 if (mode == RELEASE_MODE) { // release mode
391 if (dumperOpts.processPid_ < 0) {
392 GetConfig(CONFIG_GROUP_PROCESSES, dumpCfgs, args);
393 } else {
394 GetConfig(CONFIG_GROUP_PROCESSES_PID, dumpCfgs, args);
395 }
396 } else { // engine mode
397 if (dumperOpts.processPid_ < 0) {
398 GetConfig(CONFIG_GROUP_PROCESSES_ENG, dumpCfgs, args);
399 } else {
400 GetConfig(CONFIG_GROUP_PROCESSES_PID_ENG, dumpCfgs, args);
401 }
402
403 if (dumperOpts.IsDumpZip()) {
404 CopySmaps();
405 }
406 }
407
408 currentPidInfos_.clear();
409 currentPidInfo_.Reset();
410 return true;
411 }
412
HandleDumpFaultLog(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)413 bool ConfigUtils::HandleDumpFaultLog(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
414 {
415 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
416 if (!dumperOpts.isFaultLog_) {
417 return false;
418 }
419
420 DUMPER_HILOGD(MODULE_COMMON, "debug|fault log");
421 currentPidInfo_.Reset();
422 currentPidInfos_.clear();
423
424 std::shared_ptr<OptionArgs> args;
425 GetConfig(CONFIG_GROUP_FAULT_LOG, dumpCfgs, args);
426
427 currentPidInfos_.clear();
428 currentPidInfo_.Reset();
429 return true;
430 }
431
HandleDumpAppendix(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)432 bool ConfigUtils::HandleDumpAppendix(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
433 {
434 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
435 if (!dumperOpts.isAppendix_) {
436 return false;
437 }
438
439 DUMPER_HILOGD(MODULE_COMMON, "debug|appendix");
440 currentPidInfo_.Reset();
441 currentPidInfos_.clear();
442
443 MergePidInfos(currentPidInfos_, -1);
444 std::shared_ptr<OptionArgs> args;
445
446 GetConfig(CONFIG_GROUP_LOG_KERNEL, dumpCfgs, args);
447 GetConfig(CONFIG_GROUP_LOG_INIT, dumpCfgs, args);
448 GetConfig(CONFIG_GROUP_LOG_HILOG, dumpCfgs, args);
449 GetConfig(CONFIG_GROUP_STACK, dumpCfgs, args);
450
451 currentPidInfos_.clear();
452 currentPidInfo_.Reset();
453 return true;
454 }
455
HandleDumpTest(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs)456 bool ConfigUtils::HandleDumpTest(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs)
457 {
458 const DumperOpts &dumperOpts = dumperParam_->GetOpts();
459 if (!dumperOpts.isTest_) {
460 return false;
461 }
462
463 DUMPER_HILOGD(MODULE_COMMON, "debug|test");
464 currentPidInfo_.Reset();
465 currentPidInfos_.clear();
466
467 std::shared_ptr<OptionArgs> args;
468 GetConfig(CONFIG_GROUP_TEST, dumpCfgs, args);
469
470 currentPidInfos_.clear();
471 currentPidInfo_.Reset();
472 return true;
473 }
474
GetDumpLevelByPid(int uid,const DumpCommonUtils::PidInfo & pidInfo)475 int ConfigUtils::GetDumpLevelByPid(int uid, const DumpCommonUtils::PidInfo &pidInfo)
476 {
477 int ret = DumperConstant::LEVEL_NONE;
478 if (uid == ROOT_UID) {
479 ret = DumperConstant::LEVEL_HIGH;
480 } else if (uid < APP_FIRST_UID) {
481 ret = DumperConstant::LEVEL_MIDDLE;
482 } else {
483 ret = DumperConstant::LEVEL_LOW;
484 if (uid == pidInfo.uid_) {
485 ret = DumperConstant::LEVEL_MIDDLE;
486 }
487 }
488 return ret;
489 }
490
GetConfig(const std::string & name,std::vector<std::shared_ptr<DumpCfg>> & result,std::shared_ptr<OptionArgs> args)491 DumpStatus ConfigUtils::GetConfig(const std::string &name, std::vector<std::shared_ptr<DumpCfg>> &result,
492 std::shared_ptr<OptionArgs> args)
493 {
494 DumpStatus ret = DumpStatus::DUMP_FAIL;
495 if (name.find(CONFIG_DUMPER_) == 0) {
496 DUMPER_HILOGD(MODULE_COMMON, "debug|dumper, name=%{public}s", name.c_str());
497 ret = GetDumper(name, result, args);
498 } else if (name.find(CONFIG_GROUP_) == 0) {
499 DUMPER_HILOGD(MODULE_COMMON, "debug|group, name=%{public}s", name.c_str());
500 ret = GetGroup(name, result, args);
501 } else {
502 DUMPER_HILOGE(MODULE_COMMON, "error|name=%{public}s", name.c_str());
503 }
504 return ret;
505 }
506
GetDumper(int index,std::vector<std::shared_ptr<DumpCfg>> & result,std::shared_ptr<OptionArgs> args,int level)507 DumpStatus ConfigUtils::GetDumper(int index, std::vector<std::shared_ptr<DumpCfg>> &result,
508 std::shared_ptr<OptionArgs> args, int level)
509 {
510 if ((index < 0) || (index >= dumperSum_)) {
511 return DumpStatus::DUMP_INVALID_ARG;
512 }
513 auto itemlist = dumpers_[index].list_;
514 auto itemsize = dumpers_[index].size_;
515 for (int i = 0; i < itemsize; i++) {
516 if (DumpCfg::IsFilter(itemlist[i].class_) && DumpCfg::IsLevel(level)) {
517 if ((itemlist[i].level_ != DumperConstant::LEVEL_ALL) && (itemlist[i].level_ != level)) {
518 continue;
519 }
520 }
521 auto dumpCfg = DumpCfg::Create();
522 dumpCfg->name_ = itemlist[i].name_;
523 dumpCfg->desc_ = itemlist[i].desc_;
524 dumpCfg->target_ = itemlist[i].target_;
525 dumpCfg->section_ = itemlist[i].section_;
526 dumpCfg->class_ = itemlist[i].class_;
527 dumpCfg->level_ = itemlist[i].level_;
528 dumpCfg->loop_ = itemlist[i].loop_;
529 dumpCfg->filterCfg_ = itemlist[i].filterCfg_;
530 dumpCfg->args_ = dumpCfg->IsDumper() ? args : nullptr;
531 result.push_back(dumpCfg);
532 }
533 return DumpStatus::DUMP_OK;
534 }
535
GetDumper(const std::string & name,std::vector<std::shared_ptr<DumpCfg>> & result,std::shared_ptr<OptionArgs> args,int level)536 DumpStatus ConfigUtils::GetDumper(const std::string &name, std::vector<std::shared_ptr<DumpCfg>> &result,
537 std::shared_ptr<OptionArgs> args, int level)
538 {
539 DumpStatus ret = DumpStatus::DUMP_FAIL;
540 int index = -1;
541 for (int i = 0; i < dumperSum_; i++) {
542 if (dumpers_[i].name_.empty()) {
543 continue;
544 }
545 if (name != dumpers_[i].name_) {
546 continue;
547 }
548 index = i;
549 break;
550 }
551 if (index > -1) {
552 ret = GetDumper(index, result, args, level);
553 }
554 return ret;
555 }
556
GetGroupSimple(const GroupCfg & groupCfg,std::vector<std::shared_ptr<DumpCfg>> & result,std::shared_ptr<OptionArgs> args,int level,int nest)557 DumpStatus ConfigUtils::GetGroupSimple(const GroupCfg &groupCfg, std::vector<std::shared_ptr<DumpCfg>> &result,
558 std::shared_ptr<OptionArgs> args, int level, int nest)
559 {
560 if (nest > NEST_MAX) {
561 return DumpStatus::DUMP_INVALID_ARG;
562 }
563 if ((groupCfg.list_ == nullptr) || (groupCfg.size_ < 1)) {
564 return DumpStatus::DUMP_OK;
565 }
566
567 auto dumpGroup = DumpCfg::Create();
568 if (groupCfg.expand_) {
569 dumpGroup->class_ = DumperConstant::GROUP;
570 dumpGroup->name_ = groupCfg.name_;
571 dumpGroup->desc_ = groupCfg.desc_;
572 dumpGroup->type_ = groupCfg.type_;
573 dumpGroup->expand_ = groupCfg.expand_;
574 result.push_back(dumpGroup);
575 }
576 auto &outlist = (groupCfg.expand_) ? dumpGroup->childs_ : result;
577
578 for (int i = 0; i < groupCfg.size_; i++) {
579 if (groupCfg.list_[i].empty()) {
580 continue;
581 }
582 if (DumpCommonUtils::StartWith(groupCfg.list_[i], CONFIG_DUMPER_)) {
583 GetDumper(groupCfg.list_[i], outlist, args, level);
584 } else if (DumpCommonUtils::StartWith(groupCfg.list_[i], CONFIG_MINIGROUP_)) {
585 GetGroup(groupCfg.list_[i], outlist, args, level, nest + 1);
586 } else {
587 DUMPER_HILOGE(MODULE_COMMON, "error|name=%{public}s", groupCfg.name_.c_str());
588 return DumpStatus::DUMP_INVALID_ARG;
589 }
590 }
591
592 return DumpStatus::DUMP_OK;
593 }
594
GetGroup(int index,std::vector<std::shared_ptr<DumpCfg>> & result,std::shared_ptr<OptionArgs> args,int level,int nest)595 DumpStatus ConfigUtils::GetGroup(int index, std::vector<std::shared_ptr<DumpCfg>> &result,
596 std::shared_ptr<OptionArgs> args, int level, int nest)
597 {
598 if (nest > NEST_MAX) {
599 return DumpStatus::DUMP_INVALID_ARG;
600 }
601 auto dumpGroup = DumpCfg::Create();
602 dumpGroup->class_ = DumperConstant::GROUP;
603 dumpGroup->name_ = groups_[index].name_;
604 dumpGroup->desc_ = groups_[index].desc_;
605 dumpGroup->type_ = groups_[index].type_;
606 dumpGroup->expand_ = groups_[index].expand_;
607 result.push_back(dumpGroup);
608 if (dumpGroup->expand_ && (dumpGroup->type_ == DumperConstant::GROUPTYPE_PID)) {
609 for (auto pidInfo : currentPidInfos_) {
610 int newLevel = GetDumpLevelByPid(dumperParam_->GetUid(), pidInfo);
611 if (newLevel == DumperConstant::LEVEL_NONE) {
612 continue;
613 }
614 auto newArgs = OptionArgs::Clone(args);
615 newArgs->SetPid(pidInfo.pid_, pidInfo.uid_);
616 GetGroupSimple(groups_[index], dumpGroup->childs_, newArgs, newLevel, nest);
617 }
618 } else if (dumpGroup->expand_ && (dumpGroup->type_ == DumperConstant::GROUPTYPE_CPUID)) {
619 for (auto cpuInfo : cpuInfos_) {
620 auto newArgs = OptionArgs::Clone(args);
621 newArgs->SetCpuId(cpuInfo.id_);
622 GetGroupSimple(groups_[index], dumpGroup->childs_, newArgs, level, nest);
623 }
624 } else if (dumpGroup->type_ == DumperConstant::GROUPTYPE_PID) {
625 int newLevel = GetDumpLevelByPid(dumperParam_->GetUid(), currentPidInfo_);
626 if (newLevel != DumperConstant::LEVEL_NONE) {
627 auto newArgs = OptionArgs::Clone(args);
628 newArgs->SetPid(currentPidInfo_.pid_, currentPidInfo_.uid_);
629 GetGroupSimple(groups_[index], dumpGroup->childs_, newArgs, level, nest);
630 }
631 } else if (dumpGroup->type_ == DumperConstant::GROUPTYPE_CPUID) {
632 auto newArgs = OptionArgs::Clone(args);
633 newArgs->SetCpuId(-1);
634 GetGroupSimple(groups_[index], dumpGroup->childs_, newArgs, level, nest);
635 } else if (dumpGroup->type_ == DumperConstant::NONE) {
636 GetGroupSimple(groups_[index], dumpGroup->childs_, args, level, nest);
637 } else {
638 DUMPER_HILOGE(MODULE_COMMON, "error|type=%{public}d", dumpGroup->type_);
639 return DumpStatus::DUMP_INVALID_ARG;
640 }
641 return DumpStatus::DUMP_OK;
642 }
643
GetGroup(const std::string & name,std::vector<std::shared_ptr<DumpCfg>> & result,std::shared_ptr<OptionArgs> args,int level,int nest)644 DumpStatus ConfigUtils::GetGroup(const std::string &name, std::vector<std::shared_ptr<DumpCfg>> &result,
645 std::shared_ptr<OptionArgs> args, int level, int nest)
646 {
647 if (nest > NEST_MAX) {
648 return DumpStatus::DUMP_INVALID_ARG;
649 }
650 DumpStatus ret = DumpStatus::DUMP_FAIL;
651 int index = -1;
652 // find group
653 for (int i = 0; i < groupSum_; i++) {
654 if (groups_[i].name_.empty()) {
655 continue;
656 }
657 if (name != groups_[i].name_) {
658 continue;
659 }
660 index = i;
661 break;
662 }
663
664 // add dump config to tmpUse
665 std::vector<std::shared_ptr<DumpCfg>> tmpUse;
666 if (index > -1) {
667 ret = GetGroup(index, tmpUse, args, level);
668 }
669
670 if (nest) {
671 result.insert(result.end(), tmpUse.begin(), tmpUse.end());
672 } else {
673 // add section & add config to result
674 SetSection(tmpUse, GetSectionName(name));
675 ConvertTreeToList(tmpUse, result);
676 }
677
678 return ret;
679 }
680
ConvertTreeToList(std::vector<std::shared_ptr<DumpCfg>> & tree,std::vector<std::shared_ptr<DumpCfg>> & list,int nest)681 void ConfigUtils::ConvertTreeToList(std::vector<std::shared_ptr<DumpCfg>> &tree,
682 std::vector<std::shared_ptr<DumpCfg>> &list, int nest)
683 {
684 if (nest > NEST_MAX) {
685 return;
686 }
687
688 std::vector<std::shared_ptr<DumpCfg>> tmpUsed;
689 for (auto item : tree) {
690 if (item == nullptr) {
691 continue;
692 }
693 tmpUsed.push_back(item);
694 if (item->childs_.empty()) {
695 continue;
696 }
697 for (auto child : item->childs_) {
698 child->parent_ = item; // after point to parent, childs must be cleared.
699 }
700 ConvertTreeToList(item->childs_, tmpUsed, nest + 1);
701 item->childs_.clear(); // must clear
702 }
703
704 list.insert(list.end(), tmpUsed.begin(), tmpUsed.end());
705 }
706
SetSection(std::vector<std::shared_ptr<DumpCfg>> & dumpCfgs,const std::string & section,int nest)707 void ConfigUtils::SetSection(std::vector<std::shared_ptr<DumpCfg>> &dumpCfgs, const std::string §ion, int nest)
708 {
709 if (nest > NEST_MAX) {
710 return;
711 }
712
713 for (auto dumpCfg : dumpCfgs) {
714 if (dumpCfg == nullptr) {
715 continue;
716 }
717 if (dumpCfg->IsDumper()) {
718 dumpCfg->section_ = section;
719 }
720 if (dumpCfg->childs_.empty()) {
721 continue;
722 }
723 SetSection(dumpCfg->childs_, section, nest + 1);
724 }
725 }
726
CopySmaps()727 bool ConfigUtils::CopySmaps()
728 {
729 DUMPER_HILOGD(MODULE_COMMON, "CopySmaps enter|");
730
731 std::shared_ptr<RawParam> callback = dumperParam_->getClientCallback();
732 if (callback == nullptr) {
733 DUMPER_HILOGD(MODULE_COMMON, "CopySmaps leave|callback");
734 return false;
735 }
736
737 callback->SetProgressEnabled(true);
738 std::string logFolder = callback->GetFolder();
739 int uid = dumperParam_->GetUid();
740 for (auto &pidInfo : currentPidInfos_) {
741 int newLevel = GetDumpLevelByPid(uid, pidInfo);
742 if (newLevel == DumperConstant::LEVEL_NONE) {
743 continue;
744 }
745 if (callback->IsCanceled()) {
746 DUMPER_HILOGD(MODULE_COMMON, "CopySmaps debug|Canceled");
747 break;
748 }
749 callback->UpdateProgress(0);
750 std::string pid = std::to_string(pidInfo.pid_);
751 std::string desfolder = logFolder + SMAPS_PATH + pidInfo.name_ + "-" + pid;
752 std::string src = SMAPS_PATH_START + pid + SMAPS_PATH_END;
753 std::string des = desfolder + SMAPS_PATH_END;
754 ForceCreateDirectory(IncludeTrailingPathDelimiter(desfolder));
755 DumpUtils::CopyFile(src, des);
756 }
757
758 DUMPER_HILOGD(MODULE_COMMON, "CopySmaps leave|true");
759 return true;
760 }
761 } // namespace HiviewDFX
762 } // namespace OHOS
763