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