• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &param) : 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> &param)
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 &section, 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