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