• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"] = GetSanitizerReason(info.faultLogType, 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 
OnEvent(std::shared_ptr<Event> & event)467 bool Faultlogger::OnEvent(std::shared_ptr<Event> &event)
468 {
469     if (!hasInit_ || event == nullptr) {
470         return false;
471     }
472     if (event->eventName_ != "JS_ERROR" && event->eventName_ != "RUST_PANIC"
473         && event->eventName_ != "ADDR_SANITIZER") {
474         return true;
475     }
476     if (event->rawData_ == nullptr) {
477         return false;
478     }
479     bool isJsError = event->eventName_ == "JS_ERROR";
480     bool isRustPanic = event->eventName_ == "RUST_PANIC";
481     auto sysEvent = std::static_pointer_cast<SysEvent>(event);
482     HIVIEW_LOGI("Receive %{public}s Event:%{public}s.", event->eventName_.c_str(),
483         sysEvent->AsJsonStr().c_str());
484     FaultLogInfo info;
485     info.time = sysEvent->happenTime_;
486     info.id = sysEvent->GetUid();
487     info.pid = sysEvent->GetPid();
488     if (isJsError) {
489         info.faultLogType = FaultLogType::JS_CRASH;
490     } else {
491         info.faultLogType = isRustPanic ? FaultLogType::RUST_PANIC : FaultLogType::ADDR_SANITIZER;
492     }
493     info.module = isJsError ? sysEvent->GetEventValue("PACKAGE_NAME") : sysEvent->GetEventValue("MODULE");
494     info.reason = sysEvent->GetEventValue("REASON");
495     auto summary = sysEvent->GetEventValue("SUMMARY");
496     auto pName = isJsError ? sysEvent->GetEventValue("PNAME") : info.module;
497     info.summary = StringUtil::UnescapeJsonStringValue(summary);
498     info.sectionMap = sysEvent->GetKeyValuePairs();
499     AddFaultLog(info);
500     sysEvent->SetEventValue("FAULT_TYPE", std::to_string(info.faultLogType));
501     sysEvent->SetEventValue("MODULE", info.module);
502     sysEvent->SetEventValue("LOG_PATH", info.logPath);
503     sysEvent->SetEventValue("HAPPEN_TIME", sysEvent->happenTime_);
504     sysEvent->SetEventValue("tz_", TimeUtil::GetTimeZone());
505     sysEvent->SetEventValue("VERSION", info.sectionMap["VERSION"]);
506     sysEvent->SetEventValue("PRE_INSTALL", info.sectionMap["PRE_INSTALL"]);
507     sysEvent->SetEventValue("FOREGROUND", info.sectionMap["FOREGROUND"]);
508     std::map<std::string, std::string> eventInfos;
509     if (AnalysisFaultlog(info, eventInfos)) {
510         sysEvent->SetEventValue("PNAME", pName.empty() ? "/" : pName);
511         sysEvent->SetEventValue("FIRST_FRAME", eventInfos["FIRST_FRAME"].empty() ? "/" :
512                                 StringUtil::EscapeJsonStringValue(eventInfos["FIRST_FRAME"]));
513         sysEvent->SetEventValue("SECOND_FRAME", eventInfos["SECOND_FRAME"].empty() ? "/" :
514                                 StringUtil::EscapeJsonStringValue(eventInfos["SECOND_FRAME"]));
515         sysEvent->SetEventValue("LAST_FRAME", eventInfos["LAST_FRAME"].empty() ? "/" :
516                                 StringUtil::EscapeJsonStringValue(eventInfos["LAST_FRAME"]));
517     }
518     sysEvent->SetEventValue("FINGERPRINT", eventInfos["fingerPrint"]);
519     if (isJsError) {
520         ReportJsErrorToAppEvent(sysEvent);
521     }
522     // DEBUG FD is used for debugging and is not reported to the application.
523     // The kernel writes a special reason field to prevent reporting.
524     if (info.faultLogType == FaultLogType::ADDR_SANITIZER && info.reason != "DEBUG SIGNAL(BADFD)") {
525         ReportSanitizerToAppEvent(sysEvent);
526     }
527     return true;
528 }
529 
CanProcessEvent(std::shared_ptr<Event> event)530 bool Faultlogger::CanProcessEvent(std::shared_ptr<Event> event)
531 {
532     return true;
533 }
534 
FillHilog(const std::string & hilogStr,Json::Value & hilog) const535 void Faultlogger::FillHilog(const std::string &hilogStr, Json::Value &hilog) const
536 {
537     if (hilogStr.empty()) {
538         HIVIEW_LOGE("Get hilog is empty");
539         return;
540     }
541     std::stringstream logStream(hilogStr);
542     std::string oneLine;
543     for (int count = 0; count < REPORT_HILOG_LINE && getline(logStream, oneLine); count++) {
544         hilog.append(oneLine);
545     }
546 }
547 
ReportJsErrorToAppEvent(std::shared_ptr<SysEvent> sysEvent) const548 void Faultlogger::ReportJsErrorToAppEvent(std::shared_ptr<SysEvent> sysEvent) const
549 {
550     std::string summary = StringUtil::UnescapeJsonStringValue(sysEvent->GetEventValue("SUMMARY"));
551     HIVIEW_LOGD("ReportAppEvent:summary:%{public}s.", summary.c_str());
552 
553     Json::Value params;
554     params["time"] = sysEvent->happenTime_;
555     params["crash_type"] = "JsError";
556     std::string foreground = sysEvent->GetEventValue("FOREGROUND");
557     if (foreground == "Yes") {
558         params["foreground"] = true;
559     } else {
560         params["foreground"] = false;
561     }
562     Json::Value externalLog(Json::arrayValue);
563     std::string logPath = sysEvent->GetEventValue("LOG_PATH");
564     if (!logPath.empty()) {
565         externalLog.append(logPath);
566     }
567     params["external_log"] = externalLog;
568     params["bundle_version"] = sysEvent->GetEventValue("VERSION");
569     params["bundle_name"] = sysEvent->GetEventValue("PACKAGE_NAME");
570     params["pid"] = sysEvent->GetPid();
571     params["uid"] = sysEvent->GetUid();
572     params["uuid"] = sysEvent->GetEventValue("FINGERPRINT");
573     params["app_running_unique_id"] = sysEvent->GetEventValue("APP_RUNNING_UNIQUE_ID");
574     FillJsErrorParams(summary, params);
575     std::string log;
576     Json::Value hilog(Json::arrayValue);
577     GetHilog(sysEvent->GetPid(), log);
578     FillHilog(log, hilog);
579     params["hilog"] = hilog;
580     std::string paramsStr = Json::FastWriter().write(params);
581     HIVIEW_LOGD("ReportAppEvent: uid:%{public}d, json:%{public}s.",
582         sysEvent->GetUid(), paramsStr.c_str());
583 #ifdef UNITTEST
584     std::string outputFilePath = "/data/test_jsError_info";
585     if (!FileUtil::FileExists(outputFilePath)) {
586         int fd = TEMP_FAILURE_RETRY(open(outputFilePath.c_str(), O_CREAT | O_RDWR | O_APPEND, DEFAULT_LOG_FILE_MODE));
587         if (fd != -1) {
588             close(fd);
589         }
590     }
591     FileUtil::SaveStringToFile(outputFilePath, paramsStr, false);
592 #else
593     EventPublish::GetInstance().PushEvent(sysEvent->GetUid(), APP_CRASH_TYPE, HiSysEvent::EventType::FAULT, paramsStr);
594 #endif
595 }
596 
GetSanitizerReason(const int32_t faultLogType,const std::string & reason) const597 std::string Faultlogger::GetSanitizerReason(const int32_t faultLogType, const std::string &reason) const
598 {
599     const std::string prefix = "ASAN_";
600     const size_t pos = reason.find(prefix);
601     if (faultLogType != FaultLogType::ADDR_SANITIZER || pos == std::string::npos ||
602         pos + prefix.length() >= reason.length()) {
603             return reason;
604     }
605     return reason.substr(pos + prefix.length());
606 }
607 
ReportSanitizerToAppEvent(std::shared_ptr<SysEvent> sysEvent) const608 void Faultlogger::ReportSanitizerToAppEvent(std::shared_ptr<SysEvent> sysEvent) const
609 {
610     std::string summary = StringUtil::UnescapeJsonStringValue(sysEvent->GetEventValue("SUMMARY"));
611     HIVIEW_LOGD("ReportSanitizerAppEvent:summary:%{public}s.", summary.c_str());
612 
613     Json::Value params;
614     params["time"] = sysEvent->happenTime_;
615     std::string reason = sysEvent->GetEventValue("REASON");
616     params["type"] = GetSanitizerReason(FaultLogType::ADDR_SANITIZER, reason);
617     Json::Value externalLog(Json::arrayValue);
618     std::string logPath = sysEvent->GetEventValue("LOG_PATH");
619     if (!logPath.empty()) {
620         externalLog.append(logPath);
621     }
622     params["external_log"] = externalLog;
623     params["bundle_version"] = sysEvent->GetEventValue("VERSION");
624     params["bundle_name"] = sysEvent->GetEventValue("MODULE");
625     params["pid"] = sysEvent->GetPid();
626     params["uid"] = sysEvent->GetUid();
627     std::string paramsStr = Json::FastWriter().write(params);
628     HIVIEW_LOGD("ReportSanitizerAppEvent: uid:%{public}d, json:%{public}s.",
629         sysEvent->GetUid(), paramsStr.c_str());
630     EventPublish::GetInstance().PushEvent(sysEvent->GetUid(), "ADDRESS_SANITIZER",
631         HiSysEvent::EventType::FAULT, paramsStr);
632 }
633 
ReadyToLoad()634 bool Faultlogger::ReadyToLoad()
635 {
636     return true;
637 }
638 
OnLoad()639 void Faultlogger::OnLoad()
640 {
641     mgr_ = std::make_unique<FaultLogManager>(GetHiviewContext()->GetSharedWorkLoop());
642     mgr_->Init();
643     hasInit_ = true;
644     workLoop_ = GetHiviewContext()->GetSharedWorkLoop();
645 #ifndef UNITTEST
646     FaultloggerAdapter::StartService(this);
647 
648     // some crash happened before hiview start, ensure every crash event is added into eventdb
649     if (workLoop_ != nullptr) {
650         auto task = [this] {
651             StartBootScan();
652         };
653         workLoop_->AddTimerEvent(nullptr, nullptr, task, 10, false); // delay 10 seconds
654     }
655 #endif
656 }
657 
AddFaultLog(FaultLogInfo & info)658 void Faultlogger::AddFaultLog(FaultLogInfo& info)
659 {
660     if (!hasInit_) {
661         return;
662     }
663 
664     AddFaultLogIfNeed(info, nullptr);
665 }
666 
GetFaultLogInfo(const std::string & logPath)667 std::unique_ptr<FaultLogInfo> Faultlogger::GetFaultLogInfo(const std::string &logPath)
668 {
669     if (!hasInit_) {
670         return nullptr;
671     }
672 
673     auto info = std::make_unique<FaultLogInfo>(FaultLogger::ParseFaultLogInfoFromFile(logPath));
674     info->logPath = logPath;
675     return info;
676 }
677 
QuerySelfFaultLog(int32_t id,int32_t pid,int32_t faultType,int32_t maxNum)678 std::unique_ptr<FaultLogQueryResultInner> Faultlogger::QuerySelfFaultLog(int32_t id,
679     int32_t pid, int32_t faultType, int32_t maxNum)
680 {
681     if (!hasInit_) {
682         return nullptr;
683     }
684 
685     if ((faultType < FaultLogType::ALL) || (faultType > FaultLogType::APP_FREEZE)) {
686         HIVIEW_LOGW("Unsupported fault type");
687         return nullptr;
688     }
689 
690     if (maxNum < 0 || maxNum > MAX_QUERY_NUM) {
691         maxNum = MAX_QUERY_NUM;
692     }
693 
694     std::string name = "";
695     if (id >= MIN_APP_UID) {
696         name = GetApplicationNameById(id);
697     }
698 
699     if (name.empty()) {
700         name = CommonUtils::GetProcNameByPid(pid);
701     }
702     return std::make_unique<FaultLogQueryResultInner>(mgr_->GetFaultInfoList(name, id, faultType, maxNum));
703 }
704 
RemoveHilogFromFaultlog(const std::string & logPath,int32_t faultType) const705 void Faultlogger::RemoveHilogFromFaultlog(const std::string &logPath, int32_t faultType) const
706 {
707     std::ifstream logReadFile(logPath);
708     std::string readContent(std::istreambuf_iterator<char>(logReadFile), (std::istreambuf_iterator<char>()));
709     if (faultType == FaultLogType::CPP_CRASH) {
710         size_t pos = readContent.find("HiLog:");
711         if (pos == std::string::npos) {
712             HIVIEW_LOGW("No Hilog Found In Crash Log");
713             return;
714         }
715         readContent = readContent.substr(0, pos);
716     } else if (faultType == FaultLogType::APP_FREEZE) {
717         size_t posStart = readContent.find("catcher cmd: hilog");
718         size_t posEnd = readContent.find("catcher cmd: hidumper --cpuusage", posStart);
719         if (posStart == std::string::npos || posEnd == std::string::npos) {
720             HIVIEW_LOGW("No Hilog Found In Freeze Log");
721             return;
722         }
723         readContent.erase(posStart, posEnd - posStart);
724     }
725     std::ofstream logWriteFile(logPath);
726     logWriteFile << readContent;
727     logWriteFile.close();
728 }
729 
AddFaultLogIfNeed(FaultLogInfo & info,std::shared_ptr<Event> event)730 void Faultlogger::AddFaultLogIfNeed(FaultLogInfo& info, std::shared_ptr<Event> event)
731 {
732     if ((info.faultLogType <= FaultLogType::ALL) || (info.faultLogType > FaultLogType::ADDR_SANITIZER)) {
733         HIVIEW_LOGW("Unsupported fault type");
734         return;
735     }
736     HIVIEW_LOGI("Start saving Faultlog of Process:%{public}d, Name:%{public}s, Reason:%{public}s.",
737         info.pid, info.module.c_str(), info.reason.c_str());
738     info.sectionMap["PROCESS_NAME"] = info.module; // save process name
739     // Non system processes use UID to pass events to applications
740     bool isSystemProcess = IsSystemProcess(info.module, info.id);
741     if (!isSystemProcess) {
742         std::string appName = GetApplicationNameById(info.id);
743         if (!appName.empty()) {
744             info.module = appName; // if bundle name is not empty, replace module name by it.
745         }
746     }
747 
748     HIVIEW_LOGD("nameProc %{public}s", info.module.c_str());
749     if ((info.module.empty()) || (!IsModuleNameValid(info.module))) {
750         HIVIEW_LOGW("Invalid module name %{public}s", info.module.c_str());
751         return;
752     }
753     AddPublicInfo(info);
754     // Internal reserved fields, avoid illegal privilege escalation to access files
755     info.sectionMap.erase("APPEND_ORIGIN_LOG");
756     if (info.faultLogType == FaultLogType::CPP_CRASH) {
757         AddCppCrashInfo(info);
758     } else if (info.faultLogType == FaultLogType::APP_FREEZE) {
759         info.sectionMap["STACK"] = GetThreadStack(info.logPath, info.pid);
760     }
761 
762     mgr_->SaveFaultLogToFile(info);
763     if (info.faultLogType != FaultLogType::JS_CRASH && info.faultLogType != FaultLogType::RUST_PANIC
764         && info.faultLogType != FaultLogType::ADDR_SANITIZER) {
765         mgr_->SaveFaultInfoToRawDb(info);
766     }
767     HIVIEW_LOGI("\nSave Faultlog of Process:%{public}d\n"
768                 "ModuleName:%{public}s\n"
769                 "Reason:%{public}s\n",
770                 info.pid,
771                 info.module.c_str(),
772                 info.reason.c_str());
773 
774     if (!isSystemProcess && info.faultLogType == FaultLogType::CPP_CRASH) {
775         CheckFaultLogAsync(info);
776         ReportCppCrashToAppEvent(info);
777     } else if (!isSystemProcess && info.faultLogType == FaultLogType::APP_FREEZE) {
778         ReportAppFreezeToAppEvent(info);
779     }
780 
781     if (IsFaultLogLimit()) {
782         RemoveHilogFromFaultlog(info.logPath, info.faultLogType);
783     }
784 }
785 
OnUnorderedEvent(const Event & msg)786 void Faultlogger::OnUnorderedEvent(const Event &msg)
787 {
788 }
789 
GetListenerName()790 std::string Faultlogger::GetListenerName()
791 {
792     return "FaultLogger";
793 }
794 
StartBootScan()795 void Faultlogger::StartBootScan()
796 {
797     std::vector<std::string> files;
798     time_t now = time(nullptr);
799     FileUtil::GetDirFiles(TEMP_LOG_PATH, files);
800     for (const auto& file : files) {
801         // if file type is not cppcrash, skip!
802         if (file.find("cppcrash") == std::string::npos) {
803             HIVIEW_LOGI("Skip this file(%{public}s) that the type is not cppcrash.", file.c_str());
804             continue;
805         }
806         time_t lastAccessTime = GetFileLastAccessTimeStamp(file);
807         if ((now > lastAccessTime) && (now - lastAccessTime > FORTYEIGHT_HOURS)) {
808             HIVIEW_LOGI("Skip this file(%{public}s) that were created 48 hours ago.", file.c_str());
809             continue;
810         }
811         auto info = ParseFaultLogInfoFromFile(file, true);
812         if (info.summary.find("#00") == std::string::npos) {
813             HIVIEW_LOGI("Skip this file(%{public}s) which stack is empty.", file.c_str());
814             HiSysEventWrite(HiSysEvent::Domain::RELIABILITY, "CPP_CRASH_NO_LOG", HiSysEvent::EventType::FAULT,
815                 "PID", info.pid,
816                 "UID", info.id,
817                 "PROCESS_NAME", info.module,
818                 "HAPPEN_TIME", std::to_string(info.time)
819             );
820             if (remove(file.c_str()) != 0) {
821                 HIVIEW_LOGE("Failed to remove file(%{public}s) which stack is empty", file.c_str());
822             }
823             continue;
824         }
825         if (mgr_->IsProcessedFault(info.pid, info.id, info.faultLogType)) {
826             HIVIEW_LOGI("Skip processed fault.(%{public}d:%{public}d) ", info.pid, info.id);
827             continue;
828         }
829         AddFaultLogIfNeed(info, nullptr);
830     }
831 }
832 
ReportCppCrashToAppEvent(const FaultLogInfo & info) const833 void Faultlogger::ReportCppCrashToAppEvent(const FaultLogInfo& info) const
834 {
835     std::string stackInfo;
836     GetStackInfo(info, stackInfo);
837     if (stackInfo.length() == 0) {
838         HIVIEW_LOGE("stackInfo is empty");
839         return;
840     }
841     HIVIEW_LOGI("report cppcrash to appevent, pid:%{public}d len:%{public}zu", info.pid, stackInfo.length());
842 #ifdef UNIT_TEST
843     std::string outputFilePath = "/data/test_cppcrash_info_" + std::to_string(info.pid);
844     std::ofstream outFile(outputFilePath);
845     outFile << stackInfo << std::endl;
846     outFile.close();
847 #endif
848     EventPublish::GetInstance().PushEvent(info.id, APP_CRASH_TYPE, HiSysEvent::EventType::FAULT, stackInfo);
849 }
850 
GetStackInfo(const FaultLogInfo & info,std::string & stackInfo) const851 void Faultlogger::GetStackInfo(const FaultLogInfo& info, std::string& stackInfo) const
852 {
853     if (info.pipeFd == nullptr || *(info.pipeFd) == -1) {
854         HIVIEW_LOGE("invalid fd");
855         return;
856     }
857     ssize_t nread = -1;
858     char *buffer = new char[MAX_PIPE_SIZE];
859     nread = TEMP_FAILURE_RETRY(read(*info.pipeFd, buffer, MAX_PIPE_SIZE));
860     if (nread <= 0) {
861         HIVIEW_LOGE("read pipe failed");
862         delete []buffer;
863         return;
864     }
865     std::string stackInfoOriginal(buffer, nread);
866     delete []buffer;
867     Json::Reader reader;
868     Json::Value stackInfoObj;
869     if (!reader.parse(stackInfoOriginal, stackInfoObj)) {
870         HIVIEW_LOGE("parse stackInfo failed");
871         return;
872     }
873     stackInfoObj["bundle_name"] = info.module;
874     Json::Value externalLog;
875     externalLog.append(info.logPath);
876     stackInfoObj["external_log"] = externalLog;
877     if (info.sectionMap.count("VERSION") == 1) {
878         stackInfoObj["bundle_version"] = info.sectionMap.at("VERSION");
879     }
880     if (info.sectionMap.count("FOREGROUND") == 1) {
881         stackInfoObj["foreground"] = (info.sectionMap.at("FOREGROUND") == "Yes") ? true : false;
882     }
883     if (info.sectionMap.count("FINGERPRINT") == 1) {
884         stackInfoObj["uuid"] = info.sectionMap.at("FINGERPRINT");
885     }
886     if (info.sectionMap.count("HILOG") == 1) {
887         Json::Value hilog(Json::arrayValue);
888         auto hilogStr = info.sectionMap.at("HILOG");
889         FillHilog(hilogStr, hilog);
890         stackInfoObj["hilog"] = hilog;
891     }
892     stackInfo.append(Json::FastWriter().write(stackInfoObj));
893 }
894 
DoGetHilogProcess(int32_t pid,int writeFd) const895 int Faultlogger::DoGetHilogProcess(int32_t pid, int writeFd) const
896 {
897     HIVIEW_LOGD("Start do get hilog process, pid:%{public}d", pid);
898     if (writeFd < 0 || dup2(writeFd, STDOUT_FILENO) == -1 ||
899         dup2(writeFd, STDERR_FILENO) == -1) {
900         HIVIEW_LOGE("dup2 writeFd fail");
901         return -1;
902     }
903 
904     int ret = -1;
905     ret = execl("/system/bin/hilog", "hilog", "-z", "2000", "-P", std::to_string(pid).c_str(), nullptr);
906     if (ret < 0) {
907         HIVIEW_LOGE("execl %{public}d, errno: %{public}d", ret, errno);
908         return ret;
909     }
910     return 0;
911 }
912 
GetHilog(int32_t pid,std::string & log) const913 bool Faultlogger::GetHilog(int32_t pid, std::string& log) const
914 {
915     int fds[2] = {-1, -1}; // 2: one read pipe, one write pipe
916     if (pipe(fds) != 0) {
917         HIVIEW_LOGE("Failed to create pipe for get log.");
918         return false;
919     }
920     int childPid = fork();
921     if (childPid < 0) {
922         HIVIEW_LOGE("fork fail");
923         return false;
924     } else if (childPid == 0) {
925         syscall(SYS_close, fds[0]);
926         int rc = DoGetHilogProcess(pid, fds[1]);
927         syscall(SYS_close, fds[1]);
928         _exit(rc);
929     } else {
930         syscall(SYS_close, fds[1]);
931         // read log from fds[0]
932         while (true) {
933             char buffer[READ_HILOG_BUFFER_SIZE] = {0};
934             ssize_t nread = TEMP_FAILURE_RETRY(read(fds[0], buffer, sizeof(buffer) - 1));
935             if (nread <= 0) {
936                 HIVIEW_LOGI("read hilog finished");
937                 break;
938             }
939             log.append(buffer);
940         }
941         syscall(SYS_close, fds[0]);
942 
943         if (TEMP_FAILURE_RETRY(waitpid(childPid, nullptr, 0)) != childPid) {
944             HIVIEW_LOGE("waitpid fail, pid: %{public}d, errno: %{public}d", childPid, errno);
945             return false;
946         }
947         HIVIEW_LOGI("get hilog waitpid %{public}d success", childPid);
948         return true;
949     }
950     return false;
951 }
952 
GetDightStrArr(const std::string & target)953 std::list<std::string> GetDightStrArr(const std::string& target)
954 {
955     std::list<std::string> ret;
956     std::string temp = "";
957     for (size_t i = 0, len = target.size(); i < len; i++) {
958         if (target[i] >= '0' && target[i] <= '9') {
959             temp += target[i];
960             continue;
961         }
962         if (temp.size() != 0) {
963             ret.push_back(temp);
964             temp = "";
965         }
966     }
967     if (temp.size() != 0) {
968         ret.push_back(temp);
969     }
970     ret.push_back("0");
971     return ret;
972 }
973 
GetMemoryStrByPid(long pid) const974 std::string Faultlogger::GetMemoryStrByPid(long pid) const
975 {
976     if (pid <= 0) {
977         return "";
978     }
979     unsigned long long rss = 0; // statm col = 2 *4
980     unsigned long long vss = 0; // statm col = 1 *4
981     unsigned long long sysFreeMem = 0; // meminfo row=2
982     unsigned long long sysAvailMem = 0; // meminfo row=3
983     unsigned long long sysTotalMem = 0; // meminfo row=1
984     std::ifstream statmStream("/proc/" + std::to_string(pid) + "/statm");
985     if (statmStream) {
986         std::string statmLine;
987         std::getline(statmStream, statmLine);
988         HIVIEW_LOGI("/proc/%{public}ld/statm : %{public}s", pid, statmLine.c_str());
989         statmStream.close();
990         std::list<std::string> numStrArr = GetDightStrArr(statmLine);
991         auto it = numStrArr.begin();
992         unsigned long long multiples = 4;
993         vss = multiples * std::stoull(*it);
994         it++;
995         rss = multiples * std::stoull(*it);
996         HIVIEW_LOGI("GET FreezeJson rss=%{public}llu, vss=%{public}llu.", rss, vss);
997     } else {
998         HIVIEW_LOGE("Fail to open /proc/%{public}ld/statm", pid);
999     }
1000 
1001     std::ifstream meminfoStream("/proc/meminfo");
1002     if (meminfoStream) {
1003         std::string meminfoLine;
1004         std::getline(meminfoStream, meminfoLine);
1005         sysTotalMem = std::stoull(GetDightStrArr(meminfoLine).front());
1006         std::getline(meminfoStream, meminfoLine);
1007         sysFreeMem = std::stoull(GetDightStrArr(meminfoLine).front());
1008         std::getline(meminfoStream, meminfoLine);
1009         sysAvailMem = std::stoull(GetDightStrArr(meminfoLine).front());
1010         meminfoStream.close();
1011         HIVIEW_LOGI("GET FreezeJson sysFreeMem=%{public}llu, sysAvailMem=%{public}llu, sysTotalMem=%{public}llu.",
1012             sysFreeMem, sysAvailMem, sysTotalMem);
1013     } else {
1014         HIVIEW_LOGE("Fail to open /proc/meminfo");
1015     }
1016 
1017     FreezeJsonMemory freezeJsonMemory = FreezeJsonMemory::Builder()
1018         .InitRss(rss)
1019         .InitVss(vss)
1020         .InitSysFreeMem(sysFreeMem)
1021         .InitSysAvailMem(sysAvailMem)
1022         .InitSysTotalMem(sysTotalMem)
1023         .Build();
1024     return freezeJsonMemory.JsonStr();
1025 }
1026 
GetFreezeJsonCollector(const FaultLogInfo & info) const1027 FreezeJsonUtil::FreezeJsonCollector Faultlogger::GetFreezeJsonCollector(const FaultLogInfo& info) const
1028 {
1029     FreezeJsonUtil::FreezeJsonCollector collector = {0};
1030     std::string jsonFilePath = FreezeJsonUtil::GetFilePath(info.pid, info.id, info.time);
1031     if (!FileUtil::FileExists(jsonFilePath)) {
1032         HIVIEW_LOGE("Not Exist FreezeJsonFile: %{public}s.", jsonFilePath.c_str());
1033         return collector;
1034     }
1035     FreezeJsonUtil::LoadCollectorFromFile(jsonFilePath, collector);
1036     HIVIEW_LOGI("load FreezeJsonFile.");
1037     FreezeJsonUtil::DelFile(jsonFilePath);
1038 
1039     FreezeJsonException exception = FreezeJsonException::Builder()
1040         .InitName(collector.stringId)
1041         .InitMessage(collector.message)
1042         .Build();
1043     collector.exception = exception.JsonStr();
1044 
1045     std::list<std::string> hilogList;
1046     std::string hilogStr;
1047     GetHilog(collector.pid, hilogStr);
1048     if (hilogStr.length() == 0) {
1049         HIVIEW_LOGE("Get FreezeJson hilog is empty!");
1050     } else {
1051         std::stringstream hilogStream(hilogStr);
1052         std::string oneLine;
1053         int count = 0;
1054         while (++count <= REPORT_HILOG_LINE && std::getline(hilogStream, oneLine)) {
1055             hilogList.push_back(StringUtil::EscapeJsonStringValue(oneLine));
1056         }
1057     }
1058     collector.hilog = FreezeJsonUtil::GetStrByList(hilogList);
1059 
1060     collector.memory = GetMemoryStrByPid(collector.pid);
1061 
1062     if (info.sectionMap.count("FOREGROUND") == 1) {
1063         std::string foreground = info.sectionMap.at("FOREGROUND");
1064         collector.foreground = (foreground == "Yes");
1065     }
1066 
1067     if (info.sectionMap.count("VERSION") == 1) {
1068         collector.version = info.sectionMap.at("VERSION");
1069     }
1070 
1071     if (info.sectionMap.count("FINGERPRINT") == 1) {
1072         collector.uuid = info.sectionMap.at("FINGERPRINT");
1073     }
1074 
1075     return collector;
1076 }
1077 
ReportAppFreezeToAppEvent(const FaultLogInfo & info) const1078 void Faultlogger::ReportAppFreezeToAppEvent(const FaultLogInfo& info) const
1079 {
1080     HIVIEW_LOGI("Start to report freezeJson !!!");
1081 
1082     FreezeJsonUtil::FreezeJsonCollector collector = GetFreezeJsonCollector(info);
1083     std::list<std::string> externalLogList;
1084     externalLogList.push_back(info.logPath);
1085     std::string externalLog = FreezeJsonUtil::GetStrByList(externalLogList);
1086 
1087     FreezeJsonParams freezeJsonParams = FreezeJsonParams::Builder()
1088         .InitTime(collector.timestamp)
1089         .InitUuid(collector.uuid)
1090         .InitFreezeType("AppFreeze")
1091         .InitForeground(collector.foreground)
1092         .InitBundleVersion(collector.version)
1093         .InitBundleName(collector.package_name)
1094         .InitProcessName(collector.process_name)
1095         .InitExternalLog(externalLog)
1096         .InitPid(collector.pid)
1097         .InitUid(collector.uid)
1098         .InitAppRunningUniqueId(collector.appRunningUniqueId)
1099         .InitException(collector.exception)
1100         .InitHilog(collector.hilog)
1101         .InitEventHandler(collector.event_handler)
1102         .InitEventHandlerSize3s(collector.event_handler_3s_size)
1103         .InitEventHandlerSize6s(collector.event_handler_6s_size)
1104         .InitPeerBinder(collector.peer_binder)
1105         .InitThreads(collector.stack)
1106         .InitMemory(collector.memory)
1107         .Build();
1108     EventPublish::GetInstance().PushEvent(info.id, APP_FREEZE_TYPE,
1109         HiSysEvent::EventType::FAULT, freezeJsonParams.JsonStr());
1110     HIVIEW_LOGI("Report FreezeJson Successfully!");
1111 }
1112 
1113 /*
1114  * return value: 0 means fault log invalid; 1 means fault log valid.
1115  */
CheckFaultLog(FaultLogInfo info)1116 bool Faultlogger::CheckFaultLog(FaultLogInfo info)
1117 {
1118     int32_t err = CrashExceptionCode::CRASH_ESUCCESS;
1119     if (!CheckFaultSummaryValid(info.summary)) {
1120         err = CrashExceptionCode::CRASH_LOG_ESUMMARYLOS;
1121     }
1122     ReportCrashException(info.module, info.pid, info.id, err);
1123 
1124     return (err == CrashExceptionCode::CRASH_ESUCCESS);
1125 }
1126 
CheckFaultLogAsync(const FaultLogInfo & info)1127 void Faultlogger::CheckFaultLogAsync(const FaultLogInfo& info)
1128 {
1129     if (workLoop_ != nullptr) {
1130         auto task = [this, info] {
1131             CheckFaultLog(info);
1132         };
1133         workLoop_->AddTimerEvent(nullptr, nullptr, task, 0, false);
1134     }
1135 }
1136 } // namespace HiviewDFX
1137 } // namespace OHOS
1138 
1139