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> ¶m) : 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> ¶m)
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 §ion, 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