1 /*
2  * Copyright (c) 2021-2023 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 "faultlogger.h"
16 
17 #include <climits>
18 #include <cstdint>
19 #include <ctime>
20 #ifdef UNIT_TEST
21 #include <fstream>
22 #include <iostream>
23 #include <cstring>
24 #endif
25 #include <memory>
26 #include <regex>
27 #include <string>
28 #include <vector>
29 #include <fstream>
30 
31 #include <fcntl.h>
32 #include <sys/stat.h>
33 #include <sys/syscall.h>
34 #include <sys/types.h>
35 #include <sys/wait.h>
36 
37 #include <cerrno>
38 #include <future>
39 #include <thread>
40 #include <unistd.h>
41 
42 #include "accesstoken_kit.h"
43 #include "bundle_mgr_client.h"
44 #include "common_utils.h"
45 #include "constants.h"
46 #include "crash_exception.h"
47 #include "event.h"
48 #include "event_publish.h"
49 #include "faultlog_formatter.h"
50 #include "faultlog_info.h"
51 #include "faultlog_query_result_inner.h"
52 #include "faultlog_util.h"
53 #include "faultlogger_adapter.h"
54 #include "ffrt.h"
55 #include "file_util.h"
56 #include "hisysevent.h"
57 #include "hiview_global.h"
58 #include "ipc_skeleton.h"
59 #include "json/json.h"
60 #include "log_analyzer.h"
61 #include "hiview_logger.h"
62 #include "parameter_ex.h"
63 #include "plugin_factory.h"
64 #include "process_status.h"
65 #include "securec.h"
66 #include "string_util.h"
67 #include "sys_event_dao.h"
68 #include "time_util.h"
69 #include "zip_helper.h"
70 #include "freeze_json_generator.h"
71 #include "freeze_json_util.h"
72 
73 namespace OHOS {
74 namespace HiviewDFX {
75 REGISTER(Faultlogger);
76 DEFINE_LOG_LABEL(0xD002D11, "Faultlogger");
77 using namespace FaultLogger;
78 using namespace OHOS::AppExecFwk;
79 namespace {
80 constexpr char FILE_SEPERATOR[] = "******";
81 constexpr uint32_t DUMP_MAX_NUM = 100;
82 constexpr int32_t MAX_QUERY_NUM = 100;
83 constexpr int MIN_APP_UID = 10000;
84 constexpr int DUMP_PARSE_CMD = 0;
85 constexpr int DUMP_PARSE_FILE_NAME = 1;
86 constexpr int DUMP_PARSE_TIME = 2;
87 constexpr int DUMP_START_PARSE_MODULE_NAME = 3;
88 constexpr uint32_t MAX_NAME_LENGTH = 4096;
89 constexpr char TEMP_LOG_PATH[] = "/data/log/faultlog/temp";
90 constexpr time_t FORTYEIGHT_HOURS = 48 * 60 * 60;
91 constexpr int READ_HILOG_BUFFER_SIZE = 1024;
92 constexpr char APP_CRASH_TYPE[] = "APP_CRASH";
93 constexpr char APP_FREEZE_TYPE[] = "APP_FREEZE";
94 constexpr int REPORT_HILOG_LINE = 100;
95 constexpr const char STACK_ERROR_MESSAGE[] = "Cannot get SourceMap info, dump raw stack:";
InitDumpRequest()96 DumpRequest InitDumpRequest()
97 {
98     DumpRequest request;
99     request.requestDetail = false;
100     request.requestList = false;
101     request.fileName = "";
102     request.moduleName = "";
103     request.time = -1;
104     return request;
105 }
106 
IsLogNameValid(const std::string& name)107 bool IsLogNameValid(const std::string& name)
108 {
109     if (name.empty() || name.size() > MAX_NAME_LENGTH) {
110         HIVIEW_LOGI("invalid log name.");
111         return false;
112     }
113 
114     std::vector<std::string> out;
115     StringUtil::SplitStr(name, "-", out, true, false);
116     if (out.size() != 4) { // FileName LogType-ModuleName-uid-YYYYMMDDHHMMSS, thus contains 4 sections
117         return false;
118     }
119 
120     std::regex reType("^[a-z]+$");
121     if (!std::regex_match(out[0], reType)) { // 0 : type section
122         HIVIEW_LOGI("invalid type.");
123         return false;
124     }
125 
126     if (!IsModuleNameValid(out[1])) { // 1 : module section
127         HIVIEW_LOGI("invalid module name.");
128         return false;
129     }
130 
131     std::regex reDigits("^[0-9]*$");
132     if (!std::regex_match(out[2], reDigits)) { // 2 : uid section
133         HIVIEW_LOGI("invalid uid.");
134         return false;
135     }
136 
137     if (!std::regex_match(out[3], reDigits)) { // 3 : time section
138         HIVIEW_LOGI("invalid digits.");
139         return false;
140     }
141     return true;
142 }
143 
FillDumpRequest(DumpRequest &request, int status, const std::string &item)144 bool FillDumpRequest(DumpRequest &request, int status, const std::string &item)
145 {
146     switch (status) {
147         case DUMP_PARSE_FILE_NAME:
148             if (!IsLogNameValid(item)) {
149                 return false;
150             }
151             request.fileName = item;
152             break;
153         case DUMP_PARSE_TIME:
154             if (item.size() == 14) { // 14 : BCD time size
155                 request.time = TimeUtil::StrToTimeStamp(item, "%Y%m%d%H%M%S");
156             } else {
157                 StringUtil::ConvertStringTo<time_t>(item, request.time);
158             }
159             break;
160         case DUMP_START_PARSE_MODULE_NAME:
161             if (!IsModuleNameValid(item)) {
162                 return false;
163             }
164             request.moduleName = item;
165             break;
166         default:
167             HIVIEW_LOGI("Unknown status.");
168             break;
169     }
170     return true;
171 }
172 
GetSummaryFromSectionMap(int32_t type, const std::map<std::string, std::string>& maps)173 std::string GetSummaryFromSectionMap(int32_t type, const std::map<std::string, std::string>& maps)
174 {
175     std::string key = "";
176     switch (type) {
177         case CPP_CRASH:
178             key = "KEY_THREAD_INFO";
179             break;
180         default:
181             break;
182     }
183 
184     if (key.empty()) {
185         return "";
186     }
187 
188     auto value = maps.find(key);
189     if (value == maps.end()) {
190         return "";
191     }
192     return value->second;
193 }
194 
ParseJsErrorSummary(std::string& summary, std::string& name, std::string& message, std::string& stack)195 void ParseJsErrorSummary(std::string& summary, std::string& name, std::string& message, std::string& stack)
196 {
197     std::string leftStr = StringUtil::GetLeftSubstr(summary, "Error message:");
198     std::string rightStr = StringUtil::GetRightSubstr(summary, "Error message:");
199     name = StringUtil::GetRightSubstr(leftStr, "Error name:");
200     stack = StringUtil::GetRightSubstr(rightStr, "Stacktrace:");
201     leftStr = StringUtil::GetLeftSubstr(rightStr, "Stacktrace:");
202     do {
203         if (leftStr.find("Error code:") != std::string::npos) {
204             leftStr = StringUtil::GetLeftSubstr(leftStr, "Error code:");
205             break;
206         }
207         if (leftStr.find("SourceCode:") != std::string::npos) {
208             leftStr = StringUtil::GetLeftSubstr(leftStr, "SourceCode:");
209             break;
210         }
211     } while (false);
212     message = leftStr;
213 }
214 
FillJsErrorParams(std::string summary, Json::Value &params)215 void FillJsErrorParams(std::string summary, Json::Value &params)
216 {
217     Json::Value exception;
218     std::string name = "";
219     std::string message = "";
220     std::string stack = "";
221     do {
222         if (summary == "") {
223             break;
224         }
225         ParseJsErrorSummary(summary, name, message, stack);
226         name.erase(name.find_last_not_of("\n") + 1);
227         message.erase(message.find_last_not_of("\n") + 1);
228         if (stack.size() > 1) {
229             stack.erase(0, 1);
230             if ((stack.size() >= strlen(STACK_ERROR_MESSAGE)) &&
231                 (strcmp(STACK_ERROR_MESSAGE, stack.substr(0, strlen(STACK_ERROR_MESSAGE)).c_str()) == 0)) {
232                 stack.erase(0, strlen(STACK_ERROR_MESSAGE) + 1);
233             }
234         }
235     } while (false);
236     exception["name"] = name;
237     exception["message"] = message;
238     exception["stack"] = stack;
239     params["exception"] = exception;
240 }
241 
IsSystemProcess(const std::string &processName, int32_t uid)242 static bool IsSystemProcess(const std::string &processName, int32_t uid)
243 {
244     std::string sysBin = "/system/bin";
245     std::string venBin = "/vendor/bin";
246     return (uid < MIN_APP_USERID ||
247             (processName.compare(0, sysBin.length(), sysBin) == 0) ||
248             (processName.compare(0, venBin.length(), venBin) == 0));
249 }
250 } // namespace
251 
AddPublicInfo(FaultLogInfo &info)252 void Faultlogger::AddPublicInfo(FaultLogInfo &info)
253 {
254     info.sectionMap["DEVICE_INFO"] = Parameter::GetString("const.product.name", "Unknown");
255     if (info.sectionMap.find("BUILD_INFO") == info.sectionMap.end()) {
256         info.sectionMap["BUILD_INFO"] = Parameter::GetString("const.product.software.version", "Unknown");
257     }
258     info.sectionMap["UID"] = std::to_string(info.id);
259     info.sectionMap["PID"] = std::to_string(info.pid);
260     info.module = RegulateModuleNameIfNeed(info.module);
261     info.sectionMap["MODULE"] = info.module;
262     DfxBundleInfo bundleInfo;
263     if (info.id >= MIN_APP_USERID && GetDfxBundleInfo(info.module, bundleInfo)) {
264         if (!bundleInfo.versionName.empty()) {
265             info.sectionMap["VERSION"] = bundleInfo.versionName;
266             info.sectionMap["VERSION_CODE"] = std::to_string(bundleInfo.versionCode);
267         }
268 
269         if (bundleInfo.isPreInstalled) {
270             info.sectionMap["PRE_INSTALL"] = "Yes";
271         } else {
272             info.sectionMap["PRE_INSTALL"] = "No";
273         }
274     }
275 
276     if (info.sectionMap["FOREGROUND"].empty() && info.id >= MIN_APP_USERID) {
277         if (UCollectUtil::ProcessStatus::GetInstance().GetProcessState(info.pid) ==
278             UCollectUtil::FOREGROUND) {
279             info.sectionMap["FOREGROUND"] = "Yes";
280         } else if (UCollectUtil::ProcessStatus::GetInstance().GetProcessState(info.pid) ==
281             UCollectUtil::BACKGROUND) {
282             int64_t lastFgTime = static_cast<int64_t>(UCollectUtil::ProcessStatus::GetInstance()
283                 .GetProcessLastForegroundTime(info.pid));
284             if (lastFgTime > info.time) {
285                 info.sectionMap["FOREGROUND"] = "Yes";
286             } else {
287                 info.sectionMap["FOREGROUND"] = "No";
288             }
289         }
290     }
291 
292     if (info.reason.empty()) {
293         info.reason = info.sectionMap["REASON"];
294     } else {
295         info.sectionMap["REASON"] = info.reason;
296     }
297 
298     if (info.summary.empty()) {
299         info.summary = GetSummaryFromSectionMap(info.faultLogType, info.sectionMap);
300     } else {
301         info.sectionMap["SUMMARY"] = info.summary;
302     }
303 
304     // parse fingerprint by summary or temp log for native crash
305     AnalysisFaultlog(info, info.parsedLogInfo);
306     info.sectionMap.insert(info.parsedLogInfo.begin(), info.parsedLogInfo.end());
307     info.parsedLogInfo.clear();
308 }
309 
AddCppCrashInfo(FaultLogInfo& info)310 void Faultlogger::AddCppCrashInfo(FaultLogInfo& info)
311 {
312     if (!info.registers.empty()) {
313         info.sectionMap["KEY_THREAD_REGISTERS"] = info.registers;
314     }
315 
316     info.sectionMap["APPEND_ORIGIN_LOG"] = GetCppCrashTempLogName(info);
317 
318     std::string log;
319     GetHilog(info.pid, log);
320     info.sectionMap["HILOG"] = log;
321 }
322 
VerifiedDumpPermission()323 bool Faultlogger::VerifiedDumpPermission()
324 {
325     using namespace Security::AccessToken;
326     auto tokenId = IPCSkeleton::GetCallingTokenID();
327     if (AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.DUMP") != PermissionState::PERMISSION_GRANTED) {
328         return false;
329     }
330     return true;
331 }
332 
Dump(int fd, const std::vector<std::string> &cmds)333 void Faultlogger::Dump(int fd, const std::vector<std::string> &cmds)
334 {
335     if (!VerifiedDumpPermission()) {
336         dprintf(fd, "dump operation is not permitted.\n");
337         return;
338     }
339     auto request = InitDumpRequest();
340     int32_t status = DUMP_PARSE_CMD;
341     for (auto it = cmds.begin(); it != cmds.end(); it++) {
342         if ((*it) == "-f") {
343             status = DUMP_PARSE_FILE_NAME;
344             continue;
345         } else if ((*it) == "-l") {
346             request.requestList = true;
347             continue;
348         } else if ((*it) == "-t") {
349             status = DUMP_PARSE_TIME;
350             continue;
351         } else if ((*it) == "-m") {
352             status = DUMP_START_PARSE_MODULE_NAME;
353             continue;
354         } else if ((*it) == "-d") {
355             request.requestDetail = true;
356             continue;
357         } else if ((*it) == "Faultlogger") {
358             // skip first params
359             continue;
360         } else if ((!(*it).empty()) && ((*it).at(0) == '-')) {
361             dprintf(fd, "Unknown command.\n");
362             return;
363         }
364 
365         if (!FillDumpRequest(request, status, *it)) {
366             dprintf(fd, "invalid parameters.\n");
367             return;
368         }
369         status = DUMP_PARSE_CMD;
370     }
371 
372     if (status != DUMP_PARSE_CMD) {
373         dprintf(fd, "empty parameters.\n");
374         return;
375     }
376 
377     HIVIEW_LOGI("DumpRequest: detail:%d, list:%d, file:%s, name:%s, time:%lld",
378         request.requestDetail, request.requestList, request.fileName.c_str(), request.moduleName.c_str(),
379         static_cast<long long>(request.time));
380     Dump(fd, request);
381 }
382 
Dump(int fd, const DumpRequest &request) const383 void Faultlogger::Dump(int fd, const DumpRequest &request) const
384 {
385     if (!request.fileName.empty()) {
386         std::string content;
387         if (mgr_->GetFaultLogContent(request.fileName, content)) {
388             dprintf(fd, "%s\n", content.c_str());
389         } else {
390             dprintf(fd, "Fail to dump the log.\n");
391         }
392         return;
393     }
394 
395     auto fileList = mgr_->GetFaultLogFileList(request.moduleName, request.time, -1, 0, DUMP_MAX_NUM);
396     if (fileList.empty()) {
397         dprintf(fd, "No fault log exist.\n");
398         return;
399     }
400 
401     dprintf(fd, "Fault log list:\n");
402     dprintf(fd, "%s\n", FILE_SEPERATOR);
403     for (auto &file : fileList) {
404         std::string fileName = FileUtil::ExtractFileName(file);
405         dprintf(fd, "%s\n", fileName.c_str());
406         if (request.requestDetail) {
407             std::string content;
408             if (FileUtil::LoadStringFromFile(file, content)) {
409                 dprintf(fd, "%s\n", content.c_str());
410             } else {
411                 dprintf(fd, "Fail to dump detail log.\n");
412             }
413             dprintf(fd, "%s\n", FILE_SEPERATOR);
414         }
415     }
416     dprintf(fd, "%s\n", FILE_SEPERATOR);
417 }
418 
JudgmentRateLimiting(std::shared_ptr<Event> event)419 bool Faultlogger::JudgmentRateLimiting(std::shared_ptr<Event> event)
420 {
421     int interval = 60; // 60s time interval
422     auto sysEvent = std::static_pointer_cast<SysEvent>(event);
423     long pid = sysEvent->GetPid();
424     std::string eventPid = std::to_string(pid);
425 
426     std::time_t now = std::time(0);
427     for (auto it = eventTagTime_.begin(); it != eventTagTime_.end();) {
428         if ((now - it->second) >= interval) {
429             it = eventTagTime_.erase(it);
430             continue;
431         }
432         ++it;
433     }
434 
435     auto it = eventTagTime_.find(eventPid);
436     if (it != eventTagTime_.end()) {
437         if ((now - it->second) < interval) {
438             HIVIEW_LOGW("event: id:0x%{public}d, eventName:%{public}s pid:%{public}s. \
439                 interval:%{public}d There's not enough interval",
440                 sysEvent->eventId_, sysEvent->eventName_.c_str(), eventPid.c_str(), interval);
441             return false;
442         }
443     }
444     eventTagTime_[eventPid] = now;
445     HIVIEW_LOGI("event: id:0x%{public}d, eventName:%{public}s pid:%{public}s. \
446         interval:%{public}d normal interval",
447         sysEvent->eventId_, sysEvent->eventName_.c_str(), eventPid.c_str(), interval);
448     return true;
449 }
450 
IsInterestedPipelineEvent(std::shared_ptr<Event> event)451 bool Faultlogger::IsInterestedPipelineEvent(std::shared_ptr<Event> event)
452 {
453     if (!hasInit_ || event == nullptr) {
454         return false;
455     }
456 
457     if (event->eventName_ != "PROCESS_EXIT" &&
458         event->eventName_ != "JS_ERROR" &&
459         event->eventName_ != "RUST_PANIC"  &&
460         event->eventName_ != "ADDR_SANITIZER") {
461         return false;
462     }
463 
464     return true;
465 }
466 
FillFaultLogInfo(SysEvent &sysEvent)467 static FaultLogInfo FillFaultLogInfo(SysEvent &sysEvent)
468 {
469     FaultLogInfo info;
470     info.time = sysEvent.happenTime_;
471     info.id = sysEvent.GetUid();
472     info.pid = sysEvent.GetPid();
473     if (sysEvent.eventName_ == "JS_ERROR") {
474         info.faultLogType = FaultLogType::JS_CRASH;
475     } else if (sysEvent.eventName_ == "RUST_PANIC") {
476         info.faultLogType = FaultLogType::RUST_PANIC;
477     } else {
478         info.faultLogType = FaultLogType::ADDR_SANITIZER;
479     }
480     info.module = info.faultLogType == FaultLogType::JS_CRASH ?
481         sysEvent.GetEventValue("PACKAGE_NAME") : sysEvent.GetEventValue("MODULE");
482     info.reason = sysEvent.GetEventValue("REASON");
483     auto summary = sysEvent.GetEventValue("SUMMARY");
484     info.summary = StringUtil::UnescapeJsonStringValue(summary);
485     info.sectionMap = sysEvent.GetKeyValuePairs();
486 
487     return info;
488 }
489 
UpdateSysEvent(SysEvent &sysEvent, FaultLogInfo &info)490 static void UpdateSysEvent(SysEvent &sysEvent, FaultLogInfo &info)
491 {
492     sysEvent.SetEventValue("FAULT_TYPE", std::to_string(info.faultLogType));
493     sysEvent.SetEventValue("MODULE", info.module);
494     sysEvent.SetEventValue("LOG_PATH", info.logPath);
495     sysEvent.SetEventValue("HAPPEN_TIME", sysEvent.happenTime_);
496     sysEvent.SetEventValue("tz_", TimeUtil::GetTimeZone());
497     sysEvent.SetEventValue("VERSION", info.sectionMap["VERSION"]);
498     sysEvent.SetEventValue("PRE_INSTALL", info.sectionMap["PRE_INSTALL"]);
499     sysEvent.SetEventValue("FOREGROUND", info.sectionMap["FOREGROUND"]);
500     std::map<std::string, std::string> eventInfos;
501     if (AnalysisFaultlog(info, eventInfos)) {
502         auto pName = sysEvent.GetEventValue("PNAME");
503         if (pName.empty()) {
504             sysEvent.SetEventValue("PNAME", "/");
505         }
506         sysEvent.SetEventValue("FIRST_FRAME", eventInfos["FIRST_FRAME"].empty() ? "/" :
507                                 StringUtil::EscapeJsonStringValue(eventInfos["FIRST_FRAME"]));
508         sysEvent.SetEventValue("SECOND_FRAME", eventInfos["SECOND_FRAME"].empty() ? "/" :
509                                 StringUtil::EscapeJsonStringValue(eventInfos["SECOND_FRAME"]));
510         sysEvent.SetEventValue("LAST_FRAME", eventInfos["LAST_FRAME"].empty() ? "/" :
511                                 StringUtil::EscapeJsonStringValue(eventInfos["LAST_FRAME"]));
512     }
513     if (info.faultLogType != FaultLogType::ADDR_SANITIZER) {
514         sysEvent.SetEventValue("FINGERPRINT", eventInfos["fingerPrint"]);
515     }
516 }
517 
OnEvent(std::shared_ptr<Event> &event)518 bool Faultlogger::OnEvent(std::shared_ptr<Event> &event)
519 {
520     if (!hasInit_ || event == nullptr) {
521         return false;
522     }
523     if (event->eventName_ != "JS_ERROR" && event->eventName_ != "RUST_PANIC"
524         && event->eventName_ != "ADDR_SANITIZER") {
525         return true;
526     }
527     if (event->rawData_ == nullptr) {
528         return false;
529     }
530     auto sysEvent = std::static_pointer_cast<SysEvent>(event);
531     HIVIEW_LOGI("Receive %{public}s Event:%{public}s.", event->eventName_.c_str(), sysEvent->AsJsonStr().c_str());
532     FaultLogInfo info = FillFaultLogInfo(*sysEvent);
533     if (info.faultLogType == FaultLogType::ADDR_SANITIZER && info.summary.empty()) {
534         HIVIEW_LOGI("Skip non address_sanitizer request.");
535         return true;
536     }
537     AddFaultLog(info);
538     UpdateSysEvent(*sysEvent, info);
539     if (info.faultLogType == FaultLogType::JS_CRASH) {
540         ReportJsErrorToAppEvent(sysEvent);
541     }
542     if (info.faultLogType == FaultLogType::ADDR_SANITIZER) {
543         ReportSanitizerToAppEvent(sysEvent);
544     }
545     return true;
546 }
547 
CanProcessEvent(std::shared_ptr<Event> event)548 bool Faultlogger::CanProcessEvent(std::shared_ptr<Event> event)
549 {
550     return true;
551 }
552 
FillHilog(const std::string &hilogStr, Json::Value &hilog) const553 void Faultlogger::FillHilog(const std::string &hilogStr, Json::Value &hilog) const
554 {
555     if (hilogStr.empty()) {
556         HIVIEW_LOGE("Get hilog is empty");
557         return;
558     }
559     std::stringstream logStream(hilogStr);
560     std::string oneLine;
561     for (int count = 0; count < REPORT_HILOG_LINE && getline(logStream, oneLine); count++) {
562         hilog.append(oneLine);
563     }
564 }
565 
ReportJsErrorToAppEvent(std::shared_ptr<SysEvent> sysEvent) const566 void Faultlogger::ReportJsErrorToAppEvent(std::shared_ptr<SysEvent> sysEvent) const
567 {
568     std::string summary = StringUtil::UnescapeJsonStringValue(sysEvent->GetEventValue("SUMMARY"));
569     HIVIEW_LOGD("ReportAppEvent:summary:%{public}s.", summary.c_str());
570 
571     Json::Value params;
572     params["time"] = sysEvent->happenTime_;
573     params["crash_type"] = "JsError";
574     std::string foreground = sysEvent->GetEventValue("FOREGROUND");
575     if (foreground == "Yes") {
576         params["foreground"] = true;
577     } else {
578         params["foreground"] = false;
579     }
580     Json::Value externalLog(Json::arrayValue);
581     std::string logPath = sysEvent->GetEventValue("LOG_PATH");
582     if (!logPath.empty()) {
583         externalLog.append(logPath);
584     }
585     params["external_log"] = externalLog;
586     params["bundle_version"] = sysEvent->GetEventValue("VERSION");
587     params["bundle_name"] = sysEvent->GetEventValue("PACKAGE_NAME");
588     params["pid"] = sysEvent->GetPid();
589     params["uid"] = sysEvent->GetUid();
590     params["uuid"] = sysEvent->GetEventValue("FINGERPRINT");
591     params["app_running_unique_id"] = sysEvent->GetEventValue("APP_RUNNING_UNIQUE_ID");
592     FillJsErrorParams(summary, params);
593     std::string log;
594     Json::Value hilog(Json::arrayValue);
595     GetHilog(sysEvent->GetPid(), log);
596     FillHilog(log, hilog);
597     params["hilog"] = hilog;
598     std::string paramsStr = Json::FastWriter().write(params);
599     HIVIEW_LOGD("ReportAppEvent: uid:%{public}d, json:%{public}s.",
600         sysEvent->GetUid(), paramsStr.c_str());
601 #ifdef UNITTEST
602     std::string outputFilePath = "/data/test_jsError_info";
603     if (!FileUtil::FileExists(outputFilePath)) {
604         int fd = TEMP_FAILURE_RETRY(open(outputFilePath.c_str(), O_CREAT | O_RDWR | O_APPEND, DEFAULT_LOG_FILE_MODE));
605         if (fd != -1) {
606             close(fd);
607         }
608     }
609     FileUtil::SaveStringToFile(outputFilePath, paramsStr, false);
610 #else
611     EventPublish::GetInstance().PushEvent(sysEvent->GetUid(), APP_CRASH_TYPE, HiSysEvent::EventType::FAULT, paramsStr);
612 #endif
613 }
614 
ReportSanitizerToAppEvent(std::shared_ptr<SysEvent> sysEvent) const615 void Faultlogger::ReportSanitizerToAppEvent(std::shared_ptr<SysEvent> sysEvent) const
616 {
617     std::string summary = StringUtil::UnescapeJsonStringValue(sysEvent->GetEventValue("SUMMARY"));
618     HIVIEW_LOGD("ReportSanitizerAppEvent:summary:%{public}s.", summary.c_str());
619 
620     Json::Value params;
621     params["time"] = sysEvent->GetEventValue("HAPPEN_TIME");
622     params["type"] = sysEvent->GetEventValue("REASON");
623     Json::Value externalLog(Json::arrayValue);
624     std::string logPath = sysEvent->GetEventValue("LOG_PATH");
625     if (!logPath.empty()) {
626         externalLog.append(logPath);
627     }
628     params["external_log"] = externalLog;
629     params["bundle_version"] = sysEvent->GetEventValue("VERSION");
630     params["bundle_name"] = sysEvent->GetEventValue("MODULE");
631     params["pid"] = sysEvent->GetPid();
632     params["uid"] = sysEvent->GetUid();
633     FillJsErrorParams(summary, params);
634     std::string paramsStr = Json::FastWriter().write(params);
635     HIVIEW_LOGD("ReportSanitizerAppEvent: uid:%{public}d, json:%{public}s.",
636         sysEvent->GetUid(), paramsStr.c_str());
637     EventPublish::GetInstance().PushEvent(sysEvent->GetUid(), "ADDR_SANITIZER",
638         HiSysEvent::EventType::FAULT, paramsStr);
639 }
640 
ReadyToLoad()641 bool Faultlogger::ReadyToLoad()
642 {
643     return true;
644 }
645 
OnLoad()646 void Faultlogger::OnLoad()
647 {
648     mgr_ = std::make_unique<FaultLogManager>(GetHiviewContext()->GetSharedWorkLoop());
649     mgr_->Init();
650     hasInit_ = true;
651     workLoop_ = GetHiviewContext()->GetSharedWorkLoop();
652 #ifndef UNITTEST
653     FaultloggerAdapter::StartService(this);
654 
655     // some crash happened before hiview start, ensure every crash event is added into eventdb
656     if (workLoop_ != nullptr) {
657         auto task = [this] {
658             StartBootScan();
659         };
660         workLoop_->AddTimerEvent(nullptr, nullptr, task, 10, false); // delay 10 seconds
661     }
662 #endif
663 }
664 
AddFaultLog(FaultLogInfo& info)665 void Faultlogger::AddFaultLog(FaultLogInfo& info)
666 {
667     if (!hasInit_) {
668         return;
669     }
670 
671     AddFaultLogIfNeed(info, nullptr);
672 }
673 
GetFaultLogInfo(const std::string &logPath)674 std::unique_ptr<FaultLogInfo> Faultlogger::GetFaultLogInfo(const std::string &logPath)
675 {
676     if (!hasInit_) {
677         return nullptr;
678     }
679 
680     auto info = std::make_unique<FaultLogInfo>(FaultLogger::ParseFaultLogInfoFromFile(logPath));
681     info->logPath = logPath;
682     return info;
683 }
684 
QuerySelfFaultLog(int32_t id, int32_t pid, int32_t faultType, int32_t maxNum)685 std::unique_ptr<FaultLogQueryResultInner> Faultlogger::QuerySelfFaultLog(int32_t id,
686     int32_t pid, int32_t faultType, int32_t maxNum)
687 {
688     if (!hasInit_) {
689         return nullptr;
690     }
691 
692     if ((faultType < FaultLogType::ALL) || (faultType > FaultLogType::APP_FREEZE)) {
693         HIVIEW_LOGW("Unsupported fault type");
694         return nullptr;
695     }
696 
697     if (maxNum < 0 || maxNum > MAX_QUERY_NUM) {
698         maxNum = MAX_QUERY_NUM;
699     }
700 
701     std::string name = "";
702     if (id >= MIN_APP_UID) {
703         name = GetApplicationNameById(id);
704     }
705 
706     if (name.empty()) {
707         name = CommonUtils::GetProcNameByPid(pid);
708     }
709     return std::make_unique<FaultLogQueryResultInner>(mgr_->GetFaultInfoList(name, id, faultType, maxNum));
710 }
711 
RemoveHilogFromFaultlog(const std::string &logPath, int32_t faultType) const712 void Faultlogger::RemoveHilogFromFaultlog(const std::string &logPath, int32_t faultType) const
713 {
714     std::ifstream logReadFile(logPath);
715     std::string readContent(std::istreambuf_iterator<char>(logReadFile), (std::istreambuf_iterator<char>()));
716     if (faultType == FaultLogType::CPP_CRASH) {
717         size_t pos = readContent.find("HiLog:");
718         if (pos == std::string::npos) {
719             HIVIEW_LOGW("No Hilog Found In Crash Log");
720             return;
721         }
722         readContent.resize(pos);
723     } else if (faultType == FaultLogType::APP_FREEZE) {
724         size_t posStart = readContent.find("catcher cmd: hilog");
725         size_t posEnd = readContent.find("catcher cmd: hidumper --cpuusage", posStart);
726         if (posStart == std::string::npos || posEnd == std::string::npos) {
727             HIVIEW_LOGW("No Hilog Found In Freeze Log");
728             return;
729         }
730         readContent.erase(posStart, posEnd - posStart);
731     }
732     std::ofstream logWriteFile(logPath);
733     logWriteFile << readContent;
734     logWriteFile.close();
735 }
736 
AddFaultLogIfNeed(FaultLogInfo& info, std::shared_ptr<Event> event)737 void Faultlogger::AddFaultLogIfNeed(FaultLogInfo& info, std::shared_ptr<Event> event)
738 {
739     if ((info.faultLogType <= FaultLogType::ALL) || (info.faultLogType > FaultLogType::ADDR_SANITIZER)) {
740         HIVIEW_LOGW("Unsupported fault type");
741         return;
742     }
743     HIVIEW_LOGI("Start saving Faultlog of Process:%{public}d, Name:%{public}s, Reason:%{public}s.",
744         info.pid, info.module.c_str(), info.reason.c_str());
745     info.sectionMap["PROCESS_NAME"] = info.module; // save process name
746     // Non system processes use UID to pass events to applications
747     bool isSystemProcess = IsSystemProcess(info.module, info.id);
748     if (!isSystemProcess) {
749         std::string appName = GetApplicationNameById(info.id);
750         if (!appName.empty()) {
751             info.module = appName; // if bundle name is not empty, replace module name by it.
752         }
753     }
754 
755     HIVIEW_LOGD("nameProc %{public}s", info.module.c_str());
756     if ((info.module.empty()) || (!IsModuleNameValid(info.module))) {
757         HIVIEW_LOGW("Invalid module name %{public}s", info.module.c_str());
758         return;
759     }
760     AddPublicInfo(info);
761     // Internal reserved fields, avoid illegal privilege escalation to access files
762     info.sectionMap.erase("APPEND_ORIGIN_LOG");
763     if (info.faultLogType == FaultLogType::CPP_CRASH) {
764         AddCppCrashInfo(info);
765     } else if (info.faultLogType == FaultLogType::APP_FREEZE) {
766         info.sectionMap["STACK"] = GetThreadStack(info.logPath, info.pid);
767     }
768 
769     mgr_->SaveFaultLogToFile(info);
770     if (info.faultLogType != FaultLogType::JS_CRASH && info.faultLogType != FaultLogType::RUST_PANIC
771         && info.faultLogType != FaultLogType::ADDR_SANITIZER) {
772         mgr_->SaveFaultInfoToRawDb(info);
773     }
774     HIVIEW_LOGI("\nSave Faultlog of Process:%{public}d\n"
775                 "ModuleName:%{public}s\n"
776                 "Reason:%{public}s\n"
777                 "Summary:%{public}s\n",
778                 info.pid,
779                 info.module.c_str(),
780                 info.reason.c_str(),
781                 info.summary.c_str());
782 
783     if (!isSystemProcess && info.faultLogType == FaultLogType::CPP_CRASH) {
784         CheckFaultLogAsync(info);
785         ReportCppCrashToAppEvent(info);
786     } else if (!isSystemProcess && info.faultLogType == FaultLogType::APP_FREEZE) {
787         ReportAppFreezeToAppEvent(info);
788     }
789 
790     if (IsFaultLogLimit()) {
791         RemoveHilogFromFaultlog(info.logPath, info.faultLogType);
792     }
793 }
794 
OnUnorderedEvent(const Event &msg)795 void Faultlogger::OnUnorderedEvent(const Event &msg)
796 {
797 }
798 
GetListenerName()799 std::string Faultlogger::GetListenerName()
800 {
801     return "FaultLogger";
802 }
803 
StartBootScan()804 void Faultlogger::StartBootScan()
805 {
806     std::vector<std::string> files;
807     time_t now = time(nullptr);
808     FileUtil::GetDirFiles(TEMP_LOG_PATH, files);
809     for (const auto& file : files) {
810         // if file type is not cppcrash, skip!
811         if (file.find("cppcrash") == std::string::npos) {
812             HIVIEW_LOGI("Skip this file(%{public}s) that the type is not cppcrash.", file.c_str());
813             continue;
814         }
815         time_t lastAccessTime = GetFileLastAccessTimeStamp(file);
816         if ((now > lastAccessTime) && (now - lastAccessTime > FORTYEIGHT_HOURS)) {
817             HIVIEW_LOGI("Skip this file(%{public}s) that were created 48 hours ago.", file.c_str());
818             continue;
819         }
820         auto info = ParseFaultLogInfoFromFile(file, true);
821         if (info.summary.find("#00") == std::string::npos) {
822             HIVIEW_LOGI("Skip this file(%{public}s) which stack is empty.", file.c_str());
823             HiSysEventWrite(HiSysEvent::Domain::RELIABILITY, "CPP_CRASH_NO_LOG", HiSysEvent::EventType::FAULT,
824                 "PID", info.pid,
825                 "UID", info.id,
826                 "PROCESS_NAME", info.module,
827                 "HAPPEN_TIME", std::to_string(info.time)
828             );
829             if (remove(file.c_str()) != 0) {
830                 HIVIEW_LOGE("Failed to remove file(%{public}s) which stack is empty", file.c_str());
831             }
832             continue;
833         }
834         if (mgr_->IsProcessedFault(info.pid, info.id, info.faultLogType)) {
835             HIVIEW_LOGI("Skip processed fault.(%{public}d:%{public}d) ", info.pid, info.id);
836             continue;
837         }
838         AddFaultLogIfNeed(info, nullptr);
839     }
840 }
841 
ReportCppCrashToAppEvent(const FaultLogInfo& info) const842 void Faultlogger::ReportCppCrashToAppEvent(const FaultLogInfo& info) const
843 {
844     std::string stackInfo;
845     GetStackInfo(info, stackInfo);
846     if (stackInfo.length() == 0) {
847         HIVIEW_LOGE("stackInfo is empty");
848         return;
849     }
850     HIVIEW_LOGI("report cppcrash to appevent, pid:%{public}d len:%{public}zu", info.pid, stackInfo.length());
851 #ifdef UNIT_TEST
852     std::string outputFilePath = "/data/test_cppcrash_info_" + std::to_string(info.pid);
853     std::ofstream outFile(outputFilePath);
854     outFile << stackInfo << std::endl;
855     outFile.close();
856 #endif
857     EventPublish::GetInstance().PushEvent(info.id, APP_CRASH_TYPE, HiSysEvent::EventType::FAULT, stackInfo);
858 }
859 
GetStackInfo(const FaultLogInfo& info, std::string& stackInfo) const860 void Faultlogger::GetStackInfo(const FaultLogInfo& info, std::string& stackInfo) const
861 {
862     if (info.pipeFd == nullptr || *(info.pipeFd) == -1) {
863         HIVIEW_LOGE("invalid fd");
864         return;
865     }
866     ssize_t nread = -1;
867     char *buffer = new char[MAX_PIPE_SIZE];
868     nread = TEMP_FAILURE_RETRY(read(*info.pipeFd, buffer, MAX_PIPE_SIZE));
869     if (nread <= 0) {
870         HIVIEW_LOGE("read pipe failed");
871         delete []buffer;
872         return;
873     }
874     std::string stackInfoOriginal(buffer, nread);
875     delete []buffer;
876     Json::Reader reader;
877     Json::Value stackInfoObj;
878     if (!reader.parse(stackInfoOriginal, stackInfoObj)) {
879         HIVIEW_LOGE("parse stackInfo failed");
880         return;
881     }
882     stackInfoObj["bundle_name"] = info.module;
883     Json::Value externalLog;
884     externalLog.append(info.logPath);
885     stackInfoObj["external_log"] = externalLog;
886     if (info.sectionMap.count("VERSION") == 1) {
887         stackInfoObj["bundle_version"] = info.sectionMap.at("VERSION");
888     }
889     if (info.sectionMap.count("FOREGROUND") == 1) {
890         stackInfoObj["foreground"] = (info.sectionMap.at("FOREGROUND") == "Yes") ? true : false;
891     }
892     if (info.sectionMap.count("FINGERPRINT") == 1) {
893         stackInfoObj["uuid"] = info.sectionMap.at("FINGERPRINT");
894     }
895     if (info.sectionMap.count("HILOG") == 1) {
896         Json::Value hilog(Json::arrayValue);
897         auto hilogStr = info.sectionMap.at("HILOG");
898         FillHilog(hilogStr, hilog);
899         stackInfoObj["hilog"] = hilog;
900     }
901     stackInfo.append(Json::FastWriter().write(stackInfoObj));
902 }
903 
DoGetHilogProcess(int32_t pid, int writeFd) const904 int Faultlogger::DoGetHilogProcess(int32_t pid, int writeFd) const
905 {
906     HIVIEW_LOGD("Start do get hilog process, pid:%{public}d", pid);
907     if (writeFd < 0 || dup2(writeFd, STDOUT_FILENO) == -1 ||
908         dup2(writeFd, STDERR_FILENO) == -1) {
909         HIVIEW_LOGE("dup2 writeFd fail");
910         return -1;
911     }
912 
913     int ret = -1;
914     ret = execl("/system/bin/hilog", "hilog", "-z", "1000", "-P", std::to_string(pid).c_str(), nullptr);
915     if (ret < 0) {
916         HIVIEW_LOGE("execl %{public}d, errno: %{public}d", ret, errno);
917         return ret;
918     }
919     return 0;
920 }
921 
GetHilog(int32_t pid, std::string& log) const922 bool Faultlogger::GetHilog(int32_t pid, std::string& log) const
923 {
924     int fds[2] = {-1, -1}; // 2: one read pipe, one write pipe
925     if (pipe(fds) != 0) {
926         HIVIEW_LOGE("Failed to create pipe for get log.");
927         return false;
928     }
929     int childPid = fork();
930     if (childPid < 0) {
931         HIVIEW_LOGE("fork fail");
932         return false;
933     } else if (childPid == 0) {
934         syscall(SYS_close, fds[0]);
935         int rc = DoGetHilogProcess(pid, fds[1]);
936         syscall(SYS_close, fds[1]);
937         _exit(rc);
938     } else {
939         syscall(SYS_close, fds[1]);
940         // read log from fds[0]
941         while (true) {
942             char buffer[READ_HILOG_BUFFER_SIZE] = {0};
943             ssize_t nread = TEMP_FAILURE_RETRY(read(fds[0], buffer, sizeof(buffer) - 1));
944             if (nread <= 0) {
945                 HIVIEW_LOGI("read hilog finished");
946                 break;
947             }
948             log.append(buffer);
949         }
950         syscall(SYS_close, fds[0]);
951 
952         if (TEMP_FAILURE_RETRY(waitpid(childPid, nullptr, 0)) != childPid) {
953             HIVIEW_LOGE("waitpid fail, pid: %{public}d, errno: %{public}d", childPid, errno);
954             return false;
955         }
956         HIVIEW_LOGI("get hilog waitpid %{public}d success", childPid);
957         return true;
958     }
959     return false;
960 }
961 
GetDightStrArr(const std::string& target)962 std::list<std::string> GetDightStrArr(const std::string& target)
963 {
964     std::list<std::string> ret;
965     std::string temp = "";
966     for (size_t i = 0, len = target.size(); i < len; i++) {
967         if (target[i] >= '0' && target[i] <= '9') {
968             temp += target[i];
969             continue;
970         }
971         if (temp.size() != 0) {
972             ret.push_back(temp);
973             temp = "";
974         }
975     }
976     if (temp.size() != 0) {
977         ret.push_back(temp);
978     }
979     ret.push_back("0");
980     return ret;
981 }
982 
GetMemoryStrByPid(long pid) const983 std::string Faultlogger::GetMemoryStrByPid(long pid) const
984 {
985     if (pid <= 0) {
986         return "";
987     }
988     unsigned long long rss = 0; // statm col = 2 *4
989     unsigned long long vss = 0; // statm col = 1 *4
990     unsigned long long sysFreeMem = 0; // meminfo row=2
991     unsigned long long sysAvailMem = 0; // meminfo row=3
992     unsigned long long sysTotalMem = 0; // meminfo row=1
993     std::ifstream statmStream("/proc/" + std::to_string(pid) + "/statm");
994     if (statmStream) {
995         std::string statmLine;
996         std::getline(statmStream, statmLine);
997         HIVIEW_LOGI("/proc/%{public}ld/statm : %{public}s", pid, statmLine.c_str());
998         statmStream.close();
999         std::list<std::string> numStrArr = GetDightStrArr(statmLine);
1000         auto it = numStrArr.begin();
1001         unsigned long long multiples = 4;
1002         vss = multiples * std::stoull(*it);
1003         it++;
1004         rss = multiples * std::stoull(*it);
1005         HIVIEW_LOGI("GET FreezeJson rss=%{public}llu, vss=%{public}llu.", rss, vss);
1006     } else {
1007         HIVIEW_LOGE("Fail to open /proc/%{public}ld/statm", pid);
1008     }
1009 
1010     std::ifstream meminfoStream("/proc/meminfo");
1011     if (meminfoStream) {
1012         std::string meminfoLine;
1013         std::getline(meminfoStream, meminfoLine);
1014         sysTotalMem = std::stoull(GetDightStrArr(meminfoLine).front());
1015         std::getline(meminfoStream, meminfoLine);
1016         sysFreeMem = std::stoull(GetDightStrArr(meminfoLine).front());
1017         std::getline(meminfoStream, meminfoLine);
1018         sysAvailMem = std::stoull(GetDightStrArr(meminfoLine).front());
1019         meminfoStream.close();
1020         HIVIEW_LOGI("GET FreezeJson sysFreeMem=%{public}llu, sysAvailMem=%{public}llu, sysTotalMem=%{public}llu.",
1021             sysFreeMem, sysAvailMem, sysTotalMem);
1022     } else {
1023         HIVIEW_LOGE("Fail to open /proc/meminfo");
1024     }
1025 
1026     FreezeJsonMemory freezeJsonMemory = FreezeJsonMemory::Builder()
1027         .InitRss(rss)
1028         .InitVss(vss)
1029         .InitSysFreeMem(sysFreeMem)
1030         .InitSysAvailMem(sysAvailMem)
1031         .InitSysTotalMem(sysTotalMem)
1032         .Build();
1033     return freezeJsonMemory.JsonStr();
1034 }
1035 
GetFreezeJsonCollector(const FaultLogInfo& info) const1036 FreezeJsonUtil::FreezeJsonCollector Faultlogger::GetFreezeJsonCollector(const FaultLogInfo& info) const
1037 {
1038     FreezeJsonUtil::FreezeJsonCollector collector = {0};
1039     std::string jsonFilePath = FreezeJsonUtil::GetFilePath(info.pid, info.id, info.time);
1040     if (!FileUtil::FileExists(jsonFilePath)) {
1041         HIVIEW_LOGE("Not Exist FreezeJsonFile: %{public}s.", jsonFilePath.c_str());
1042         return collector;
1043     }
1044     FreezeJsonUtil::LoadCollectorFromFile(jsonFilePath, collector);
1045     HIVIEW_LOGI("load FreezeJsonFile.");
1046     FreezeJsonUtil::DelFile(jsonFilePath);
1047 
1048     FreezeJsonException exception = FreezeJsonException::Builder()
1049         .InitName(collector.stringId)
1050         .InitMessage(collector.message)
1051         .Build();
1052     collector.exception = exception.JsonStr();
1053 
1054     std::list<std::string> hilogList;
1055     std::string hilogStr;
1056     GetHilog(collector.pid, hilogStr);
1057     if (hilogStr.length() == 0) {
1058         HIVIEW_LOGE("Get FreezeJson hilog is empty!");
1059     } else {
1060         std::stringstream hilogStream(hilogStr);
1061         std::string oneLine;
1062         int count = 0;
1063         while (++count <= REPORT_HILOG_LINE && std::getline(hilogStream, oneLine)) {
1064             hilogList.push_back(StringUtil::EscapeJsonStringValue(oneLine));
1065         }
1066     }
1067     collector.hilog = FreezeJsonUtil::GetStrByList(hilogList);
1068 
1069     collector.memory = GetMemoryStrByPid(collector.pid);
1070 
1071     if (info.sectionMap.count("FOREGROUND") == 1) {
1072         std::string foreground = info.sectionMap.at("FOREGROUND");
1073         collector.foreground = (foreground == "Yes");
1074     }
1075 
1076     if (info.sectionMap.count("VERSION") == 1) {
1077         collector.version = info.sectionMap.at("VERSION");
1078     }
1079 
1080     if (info.sectionMap.count("FINGERPRINT") == 1) {
1081         collector.uuid = info.sectionMap.at("FINGERPRINT");
1082     }
1083 
1084     return collector;
1085 }
1086 
ReportAppFreezeToAppEvent(const FaultLogInfo& info) const1087 void Faultlogger::ReportAppFreezeToAppEvent(const FaultLogInfo& info) const
1088 {
1089     HIVIEW_LOGI("Start to report freezeJson !!!");
1090 
1091     FreezeJsonUtil::FreezeJsonCollector collector = GetFreezeJsonCollector(info);
1092     std::list<std::string> externalLogList;
1093     externalLogList.push_back(info.logPath);
1094     std::string externalLog = FreezeJsonUtil::GetStrByList(externalLogList);
1095 
1096     FreezeJsonParams freezeJsonParams = FreezeJsonParams::Builder()
1097         .InitTime(collector.timestamp)
1098         .InitUuid(collector.uuid)
1099         .InitFreezeType("AppFreeze")
1100         .InitForeground(collector.foreground)
1101         .InitBundleVersion(collector.version)
1102         .InitBundleName(collector.package_name)
1103         .InitProcessName(collector.process_name)
1104         .InitExternalLog(externalLog)
1105         .InitPid(collector.pid)
1106         .InitUid(collector.uid)
1107         .InitAppRunningUniqueId(collector.appRunningUniqueId)
1108         .InitException(collector.exception)
1109         .InitHilog(collector.hilog)
1110         .InitEventHandler(collector.event_handler)
1111         .InitEventHandlerSize3s(collector.event_handler_3s_size)
1112         .InitEventHandlerSize6s(collector.event_handler_6s_size)
1113         .InitPeerBinder(collector.peer_binder)
1114         .InitThreads(collector.stack)
1115         .InitMemory(collector.memory)
1116         .Build();
1117     EventPublish::GetInstance().PushEvent(info.id, APP_FREEZE_TYPE,
1118         HiSysEvent::EventType::FAULT, freezeJsonParams.JsonStr());
1119     HIVIEW_LOGI("Report FreezeJson Successfully!");
1120 }
1121 
1122 /*
1123  * return value: 0 means fault log invalid; 1 means fault log valid.
1124  */
CheckFaultLog(FaultLogInfo info)1125 bool Faultlogger::CheckFaultLog(FaultLogInfo info)
1126 {
1127     int32_t err = CrashExceptionCode::CRASH_ESUCCESS;
1128     if (!CheckFaultSummaryValid(info.summary)) {
1129         err = CrashExceptionCode::CRASH_LOG_ESUMMARYLOS;
1130     }
1131     ReportCrashException(info.module, info.pid, info.id, err);
1132 
1133     return (err == CrashExceptionCode::CRASH_ESUCCESS);
1134 }
1135 
CheckFaultLogAsync(const FaultLogInfo& info)1136 void Faultlogger::CheckFaultLogAsync(const FaultLogInfo& info)
1137 {
1138     if (workLoop_ != nullptr) {
1139         auto task = [this, info] {
1140             CheckFaultLog(info);
1141         };
1142         workLoop_->AddTimerEvent(nullptr, nullptr, task, 0, false);
1143     }
1144 }
1145 } // namespace HiviewDFX
1146 } // namespace OHOS
1147 
1148