• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "process_dump_config.h"
17 
18 #include <cstdio>
19 #include <cstdlib>
20 #include <map>
21 #include <mutex>
22 #include <securec.h>
23 #include <string>
24 #ifndef is_ohos_lite
25 #include "cJSON.h"
26 #endif
27 #include "dfx_define.h"
28 #include "dfx_log.h"
29 #include "file_ex.h"
30 #include "string_util.h"
31 
32 namespace OHOS {
33 namespace HiviewDFX {
34 namespace {
35 #undef LOG_DOMAIN
36 #undef LOG_TAG
37 #define LOG_DOMAIN 0xD002D11
38 #define LOG_TAG "ProcessDumpConfig"
39 
40 const char* const KEY_THREAD_DUMP_INFO = "KeyThreadDumpInfo";
41 const char* const DUMP_INFO_HEADER = "DumpInfoHeader";
42 const char* const SUBMITTER_STACK = "SubmitterStack";
43 const char* const REGISTERS = "Registers";
44 const char* const EXTRA_CRASH_INFO = "ExtraCrashInfo";
45 const char* const OTHER_THREAD_DUMP_INFO = "OtherThreadDumpInfo";
46 const char* const MEMORY_NEAR_REGISTER = "MemoryNearRegister";
47 const char* const FAULT_STACK = "FaultStack";
48 const char* const MAPS = "Maps";
49 const char* const OPEN_FILES = "OpenFiles";
50 #ifndef is_ohos_lite
51 constexpr int32_t MAX_NUM_INT32 = std::numeric_limits<int32_t>::max();
52 const char* const DUMP_INFO_COMPONENT_NAME[] = {
53     KEY_THREAD_DUMP_INFO, DUMP_INFO_HEADER, SUBMITTER_STACK, REGISTERS, EXTRA_CRASH_INFO,
54     OTHER_THREAD_DUMP_INFO, MEMORY_NEAR_REGISTER, FAULT_STACK, MAPS, OPEN_FILES,
55 };
56 const char* const PROCESS_DUMP_CONF_PATH = "/system/etc/faultlogger.conf";
GetStringValueFromJson(const cJSON * json,std::string defaultValue="")57 std::string GetStringValueFromJson(const cJSON* json, std::string defaultValue = "")
58 {
59     if (!cJSON_IsString(json)) {
60         return defaultValue;
61     }
62     return json->valuestring;
63 }
64 
GetInt32ValueFromJson(const cJSON * json,int32_t defaultValue=0)65 int32_t GetInt32ValueFromJson(const cJSON* json, int32_t defaultValue = 0)
66 {
67     if (!cJSON_IsNumber(json)) {
68         return defaultValue;
69     }
70     return json->valueint;
71 }
72 
GetBoolValueFromJson(const cJSON * json,bool defaultValue=false)73 bool GetBoolValueFromJson(const cJSON* json, bool defaultValue = false)
74 {
75     if (!cJSON_IsBool(json)) {
76         return defaultValue;
77     }
78     return cJSON_IsTrue(json) == 1;
79 }
80 
ParseDumpInfoConfig(const cJSON * json,DumpConfig & dumpConfig)81 void ParseDumpInfoConfig(const cJSON* json, DumpConfig& dumpConfig)
82 {
83     auto* dumpInfos = cJSON_GetObjectItem(json, "DumpInfos");
84     if (dumpInfos == nullptr) {
85         DFXLOGE("Failed to Parse Dump Info Config!");
86         return;
87     }
88     if (!cJSON_IsArray(dumpInfos)) {
89         DFXLOGE("dumpInfos is not array!");
90         return;
91     }
92     int size = cJSON_GetArraySize(dumpInfos);
93     for (int i = 0; i < size; i++) {
94         auto* dumpInfo = cJSON_GetArrayItem(dumpInfos, i);
95         int32_t code = GetInt32ValueFromJson(cJSON_GetObjectItem(dumpInfo, "Code"));
96         std::string typeName = GetStringValueFromJson(cJSON_GetObjectItem(dumpInfo, "TypeName"));
97         std::vector<std::string> dumpInfoComponent;
98         for (const auto& componentName : DUMP_INFO_COMPONENT_NAME) {
99             if (GetBoolValueFromJson(cJSON_GetObjectItem(dumpInfo, componentName))) {
100                 dumpInfoComponent.emplace_back(componentName);
101             }
102         }
103         dumpConfig.dumpInfo[static_cast<ProcessDumpType>(code)] = dumpInfoComponent;
104     }
105 }
106 
ParseConfig(const cJSON * json,DumpConfig & dumpConfig)107 void ParseConfig(const cJSON* json, DumpConfig& dumpConfig)
108 {
109     if (json == nullptr) {
110         DFXLOGE("failed to Parse directoryConfig");
111         return;
112     }
113     dumpConfig.maxFrameNums = std::clamp(
114         GetInt32ValueFromJson(cJSON_GetObjectItem(json, "maxFrameNums")), 0, MAX_NUM_INT32);
115     dumpConfig.faultStackLowAddrStep = std::clamp(
116         GetInt32ValueFromJson(cJSON_GetObjectItem(json, "faultStackLowAddrStep")), 0, MAX_NUM_INT32);
117     dumpConfig.faultStackHighAddrStep = std::clamp(
118         GetInt32ValueFromJson(cJSON_GetObjectItem(json, "faultStackHighAddrStep")), 0, MAX_NUM_INT32);
119     dumpConfig.extendPcLrPrinting = GetBoolValueFromJson(cJSON_GetObjectItem(json, "extendPcLrPrinting"));
120     dumpConfig.simplifyVmaPrinting = GetBoolValueFromJson(cJSON_GetObjectItem(json, "simplifyVmaPrinting"));
121     dumpConfig.reservedParseSymbolTime = std::clamp(
122         GetInt32ValueFromJson(cJSON_GetObjectItem(json, "reservedParseSymbolTime")), 0, MAX_NUM_INT32);
123     ParseDumpInfoConfig(json, dumpConfig);
124 }
125 #endif
126 }
127 
GetInstance()128 ProcessDumpConfig& ProcessDumpConfig::GetInstance()
129 {
130     static ProcessDumpConfig processDumpConfig;
131     return processDumpConfig;
132 }
133 
134 #ifndef is_ohos_lite
ProcessDumpConfig()135 ProcessDumpConfig::ProcessDumpConfig()
136 {
137     std::string content;
138     OHOS::LoadStringFromFile(PROCESS_DUMP_CONF_PATH, content);
139     cJSON* json = cJSON_Parse(content.c_str());
140     if (json == nullptr) {
141         DFXLOGE("failed to parse json from the content of file(%{public}s).", PROCESS_DUMP_CONF_PATH);
142         LoadDefaultConfig();
143         return;
144     }
145     ParseConfig(json, dumpConfig_);
146     cJSON_Delete(json);
147 }
148 #else
ProcessDumpConfig()149 ProcessDumpConfig::ProcessDumpConfig()
150 {
151     LoadDefaultConfig();
152 }
153 #endif
154 
LoadDefaultConfig()155 void ProcessDumpConfig::LoadDefaultConfig()
156 {
157     dumpConfig_.dumpInfo[ProcessDumpType::DUMP_TYPE_CPP_CRASH] = {
158         KEY_THREAD_DUMP_INFO, DUMP_INFO_HEADER, SUBMITTER_STACK,
159         REGISTERS, EXTRA_CRASH_INFO, OTHER_THREAD_DUMP_INFO,
160         MEMORY_NEAR_REGISTER, FAULT_STACK, MAPS, OPEN_FILES,
161     };
162     dumpConfig_.dumpInfo[ProcessDumpType::DUMP_TYPE_DUMP_CATCH] = {
163         KEY_THREAD_DUMP_INFO, DUMP_INFO_HEADER, OTHER_THREAD_DUMP_INFO,
164     };
165     dumpConfig_.dumpInfo[ProcessDumpType::DUMP_TYPE_MEM_LEAK] = {
166         KEY_THREAD_DUMP_INFO, DUMP_INFO_HEADER, REGISTERS,
167         MEMORY_NEAR_REGISTER, FAULT_STACK, MAPS,
168     };
169     dumpConfig_.dumpInfo[ProcessDumpType::DUMP_TYPE_FDSAN] = {
170         KEY_THREAD_DUMP_INFO, DUMP_INFO_HEADER, REGISTERS,
171         MEMORY_NEAR_REGISTER, FAULT_STACK, MAPS, OPEN_FILES,
172     };
173     dumpConfig_.dumpInfo[ProcessDumpType::DUMP_TYPE_JEMALLOC] = {
174         KEY_THREAD_DUMP_INFO, DUMP_INFO_HEADER, REGISTERS,
175         MEMORY_NEAR_REGISTER, FAULT_STACK, MAPS,
176     };
177     dumpConfig_.dumpInfo[ProcessDumpType::DUMP_TYPE_BADFD] = {
178         KEY_THREAD_DUMP_INFO, DUMP_INFO_HEADER, REGISTERS,
179         MEMORY_NEAR_REGISTER, FAULT_STACK, MAPS, OPEN_FILES,
180     };
181     dumpConfig_.dumpInfo[ProcessDumpType::DUMP_TYPE_COREDUMP] = {
182         KEY_THREAD_DUMP_INFO, REGISTERS, OTHER_THREAD_DUMP_INFO,
183     };
184 }
185 
GetConfig() const186 const DumpConfig& ProcessDumpConfig::GetConfig() const
187 {
188     return dumpConfig_;
189 }
190 } // namespace HiviewDFX
191 } // namespace OHOS
192