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 ¶ms)
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