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