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
16 #include "dfx_config.h"
17
18 #include <cstdio>
19 #include <cstdlib>
20 #include <map>
21 #include <mutex>
22 #include <securec.h>
23 #include <string>
24 #include "dfx_define.h"
25 #include "dfx_log.h"
26 #include "string_util.h"
27
28 namespace OHOS {
29 namespace HiviewDFX {
30 namespace {
31 #undef LOG_DOMAIN
32 #undef LOG_TAG
33 #define LOG_DOMAIN 0xD002D11
34 #define LOG_TAG "DfxConfig"
35
36 const char FAULTLOGGER_CONF_PATH[] = "/system/etc/faultlogger.conf";
37 const int CONF_LINE_SIZE = 256;
38 }
39
GetConfig()40 DfxConfigInfo& DfxConfig::GetConfig()
41 {
42 static DfxConfigInfo config;
43 static std::once_flag flag;
44 std::call_once(flag, [&] {
45 ReadAndParseConfig(config);
46 });
47 return config;
48 }
49
InitConfigMaps(DfxConfigInfo & config,std::map<std::string,bool * > & boolConfig,std::map<std::string,unsigned int * > & uintConfig)50 void DfxConfig::InitConfigMaps(DfxConfigInfo& config, std::map<std::string, bool *>& boolConfig,
51 std::map<std::string, unsigned int *>& uintConfig)
52 {
53 boolConfig = {
54 {std::string("displayRegister"), &(config.displayRegister)},
55 {std::string("displayBacktrace"), &(config.displayBacktrace)},
56 {std::string("displayMaps"), &(config.displayMaps)},
57 {std::string("displayFaultStack.switch"), &(config.displayFaultStack)},
58 {std::string("dumpOtherThreads"), &(config.dumpOtherThreads)},
59 };
60 uintConfig = {
61 {std::string("displayFaultStack.lowAddressStep"), &(config.lowAddressStep)},
62 {std::string("displayFaultStack.highAddressStep"), &(config.highAddressStep)},
63 {std::string("maxFrameNums"), &(config.maxFrameNums)},
64 };
65 }
66
ReadAndParseConfig(DfxConfigInfo & config)67 void DfxConfig::ReadAndParseConfig(DfxConfigInfo& config)
68 {
69 char codeBuffer[CONF_LINE_SIZE] = {0};
70 FILE *fp = fopen(FAULTLOGGER_CONF_PATH, "r");
71 if (fp == nullptr) {
72 DFXLOGW("Failed to open %{public}s. Reason: %{public}s.", FAULTLOGGER_CONF_PATH, strerror(errno));
73 return;
74 }
75 std::map<std::string, bool *> boolConfig;
76 std::map<std::string, unsigned int *> uintConfig;
77 InitConfigMaps(config, boolConfig, uintConfig);
78
79 auto boolConfigParser = [](bool* configProp, const std::string& value) {
80 *configProp = (value != "false");
81 };
82 auto uintConfigParser = [](unsigned int* configProp, const std::string& value) {
83 unsigned int propValue = static_cast<unsigned int>(atoi(value.data()));
84 if (propValue != 0) {
85 *configProp = propValue;
86 }
87 };
88
89 while (!feof(fp)) {
90 (void)memset_s(codeBuffer, sizeof(codeBuffer), '\0', sizeof(codeBuffer));
91 if (fgets(codeBuffer, CONF_LINE_SIZE - 1, fp) == nullptr) {
92 continue;
93 }
94 std::string line(codeBuffer);
95 std::string::size_type newLinePos = line.find_first_of("\n");
96 if (newLinePos != line.npos) {
97 line.resize(newLinePos);
98 }
99 std::string::size_type equalSignPos = line.find_first_of("=");
100 if (equalSignPos != line.npos) {
101 std::string key = line.substr(0, equalSignPos);
102 std::string value = line.substr(equalSignPos + 1);
103 Trim(key);
104 Trim(value);
105 if (boolConfig.find(key) != boolConfig.end()) {
106 boolConfigParser(boolConfig[key], value);
107 } else if (uintConfig.find(key) != uintConfig.end()) {
108 uintConfigParser(uintConfig[key], value);
109 }
110 }
111 }
112 (void)fclose(fp);
113 }
114 } // namespace HiviewDFX
115 } // namespace OHOS
116