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 ¶ms)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"] = info.reason;
296 }
297
298 if (info.summary.empty()) {
299 info.summary = GetSummaryFromSectionMap(info.faultLogType, info.sectionMap);
300 } else {
301 info.sectionMap["SUMMARY"] = info.summary;
302 }
303
304 // parse fingerprint by summary or temp log for native crash
305 AnalysisFaultlog(info, info.parsedLogInfo);
306 info.sectionMap.insert(info.parsedLogInfo.begin(), info.parsedLogInfo.end());
307 info.parsedLogInfo.clear();
308 }
309
AddCppCrashInfo(FaultLogInfo& info)310 void Faultlogger::AddCppCrashInfo(FaultLogInfo& info)
311 {
312 if (!info.registers.empty()) {
313 info.sectionMap["KEY_THREAD_REGISTERS"] = info.registers;
314 }
315
316 info.sectionMap["APPEND_ORIGIN_LOG"] = GetCppCrashTempLogName(info);
317
318 std::string log;
319 GetHilog(info.pid, log);
320 info.sectionMap["HILOG"] = log;
321 }
322
VerifiedDumpPermission()323 bool Faultlogger::VerifiedDumpPermission()
324 {
325 using namespace Security::AccessToken;
326 auto tokenId = IPCSkeleton::GetCallingTokenID();
327 if (AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.DUMP") != PermissionState::PERMISSION_GRANTED) {
328 return false;
329 }
330 return true;
331 }
332
Dump(int fd, const std::vector<std::string> &cmds)333 void Faultlogger::Dump(int fd, const std::vector<std::string> &cmds)
334 {
335 if (!VerifiedDumpPermission()) {
336 dprintf(fd, "dump operation is not permitted.\n");
337 return;
338 }
339 auto request = InitDumpRequest();
340 int32_t status = DUMP_PARSE_CMD;
341 for (auto it = cmds.begin(); it != cmds.end(); it++) {
342 if ((*it) == "-f") {
343 status = DUMP_PARSE_FILE_NAME;
344 continue;
345 } else if ((*it) == "-l") {
346 request.requestList = true;
347 continue;
348 } else if ((*it) == "-t") {
349 status = DUMP_PARSE_TIME;
350 continue;
351 } else if ((*it) == "-m") {
352 status = DUMP_START_PARSE_MODULE_NAME;
353 continue;
354 } else if ((*it) == "-d") {
355 request.requestDetail = true;
356 continue;
357 } else if ((*it) == "Faultlogger") {
358 // skip first params
359 continue;
360 } else if ((!(*it).empty()) && ((*it).at(0) == '-')) {
361 dprintf(fd, "Unknown command.\n");
362 return;
363 }
364
365 if (!FillDumpRequest(request, status, *it)) {
366 dprintf(fd, "invalid parameters.\n");
367 return;
368 }
369 status = DUMP_PARSE_CMD;
370 }
371
372 if (status != DUMP_PARSE_CMD) {
373 dprintf(fd, "empty parameters.\n");
374 return;
375 }
376
377 HIVIEW_LOGI("DumpRequest: detail:%d, list:%d, file:%s, name:%s, time:%lld",
378 request.requestDetail, request.requestList, request.fileName.c_str(), request.moduleName.c_str(),
379 static_cast<long long>(request.time));
380 Dump(fd, request);
381 }
382
Dump(int fd, const DumpRequest &request) const383 void Faultlogger::Dump(int fd, const DumpRequest &request) const
384 {
385 if (!request.fileName.empty()) {
386 std::string content;
387 if (mgr_->GetFaultLogContent(request.fileName, content)) {
388 dprintf(fd, "%s\n", content.c_str());
389 } else {
390 dprintf(fd, "Fail to dump the log.\n");
391 }
392 return;
393 }
394
395 auto fileList = mgr_->GetFaultLogFileList(request.moduleName, request.time, -1, 0, DUMP_MAX_NUM);
396 if (fileList.empty()) {
397 dprintf(fd, "No fault log exist.\n");
398 return;
399 }
400
401 dprintf(fd, "Fault log list:\n");
402 dprintf(fd, "%s\n", FILE_SEPERATOR);
403 for (auto &file : fileList) {
404 std::string fileName = FileUtil::ExtractFileName(file);
405 dprintf(fd, "%s\n", fileName.c_str());
406 if (request.requestDetail) {
407 std::string content;
408 if (FileUtil::LoadStringFromFile(file, content)) {
409 dprintf(fd, "%s\n", content.c_str());
410 } else {
411 dprintf(fd, "Fail to dump detail log.\n");
412 }
413 dprintf(fd, "%s\n", FILE_SEPERATOR);
414 }
415 }
416 dprintf(fd, "%s\n", FILE_SEPERATOR);
417 }
418
JudgmentRateLimiting(std::shared_ptr<Event> event)419 bool Faultlogger::JudgmentRateLimiting(std::shared_ptr<Event> event)
420 {
421 int interval = 60; // 60s time interval
422 auto sysEvent = std::static_pointer_cast<SysEvent>(event);
423 long pid = sysEvent->GetPid();
424 std::string eventPid = std::to_string(pid);
425
426 std::time_t now = std::time(0);
427 for (auto it = eventTagTime_.begin(); it != eventTagTime_.end();) {
428 if ((now - it->second) >= interval) {
429 it = eventTagTime_.erase(it);
430 continue;
431 }
432 ++it;
433 }
434
435 auto it = eventTagTime_.find(eventPid);
436 if (it != eventTagTime_.end()) {
437 if ((now - it->second) < interval) {
438 HIVIEW_LOGW("event: id:0x%{public}d, eventName:%{public}s pid:%{public}s. \
439 interval:%{public}d There's not enough interval",
440 sysEvent->eventId_, sysEvent->eventName_.c_str(), eventPid.c_str(), interval);
441 return false;
442 }
443 }
444 eventTagTime_[eventPid] = now;
445 HIVIEW_LOGI("event: id:0x%{public}d, eventName:%{public}s pid:%{public}s. \
446 interval:%{public}d normal interval",
447 sysEvent->eventId_, sysEvent->eventName_.c_str(), eventPid.c_str(), interval);
448 return true;
449 }
450
IsInterestedPipelineEvent(std::shared_ptr<Event> event)451 bool Faultlogger::IsInterestedPipelineEvent(std::shared_ptr<Event> event)
452 {
453 if (!hasInit_ || event == nullptr) {
454 return false;
455 }
456
457 if (event->eventName_ != "PROCESS_EXIT" &&
458 event->eventName_ != "JS_ERROR" &&
459 event->eventName_ != "RUST_PANIC" &&
460 event->eventName_ != "ADDR_SANITIZER") {
461 return false;
462 }
463
464 return true;
465 }
466
FillFaultLogInfo(SysEvent &sysEvent)467 static FaultLogInfo FillFaultLogInfo(SysEvent &sysEvent)
468 {
469 FaultLogInfo info;
470 info.time = sysEvent.happenTime_;
471 info.id = sysEvent.GetUid();
472 info.pid = sysEvent.GetPid();
473 if (sysEvent.eventName_ == "JS_ERROR") {
474 info.faultLogType = FaultLogType::JS_CRASH;
475 } else if (sysEvent.eventName_ == "RUST_PANIC") {
476 info.faultLogType = FaultLogType::RUST_PANIC;
477 } else {
478 info.faultLogType = FaultLogType::ADDR_SANITIZER;
479 }
480 info.module = info.faultLogType == FaultLogType::JS_CRASH ?
481 sysEvent.GetEventValue("PACKAGE_NAME") : sysEvent.GetEventValue("MODULE");
482 info.reason = sysEvent.GetEventValue("REASON");
483 auto summary = sysEvent.GetEventValue("SUMMARY");
484 info.summary = StringUtil::UnescapeJsonStringValue(summary);
485 info.sectionMap = sysEvent.GetKeyValuePairs();
486
487 return info;
488 }
489
UpdateSysEvent(SysEvent &sysEvent, FaultLogInfo &info)490 static void UpdateSysEvent(SysEvent &sysEvent, FaultLogInfo &info)
491 {
492 sysEvent.SetEventValue("FAULT_TYPE", std::to_string(info.faultLogType));
493 sysEvent.SetEventValue("MODULE", info.module);
494 sysEvent.SetEventValue("LOG_PATH", info.logPath);
495 sysEvent.SetEventValue("HAPPEN_TIME", sysEvent.happenTime_);
496 sysEvent.SetEventValue("tz_", TimeUtil::GetTimeZone());
497 sysEvent.SetEventValue("VERSION", info.sectionMap["VERSION"]);
498 sysEvent.SetEventValue("PRE_INSTALL", info.sectionMap["PRE_INSTALL"]);
499 sysEvent.SetEventValue("FOREGROUND", info.sectionMap["FOREGROUND"]);
500 std::map<std::string, std::string> eventInfos;
501 if (AnalysisFaultlog(info, eventInfos)) {
502 auto pName = sysEvent.GetEventValue("PNAME");
503 if (pName.empty()) {
504 sysEvent.SetEventValue("PNAME", "/");
505 }
506 sysEvent.SetEventValue("FIRST_FRAME", eventInfos["FIRST_FRAME"].empty() ? "/" :
507 StringUtil::EscapeJsonStringValue(eventInfos["FIRST_FRAME"]));
508 sysEvent.SetEventValue("SECOND_FRAME", eventInfos["SECOND_FRAME"].empty() ? "/" :
509 StringUtil::EscapeJsonStringValue(eventInfos["SECOND_FRAME"]));
510 sysEvent.SetEventValue("LAST_FRAME", eventInfos["LAST_FRAME"].empty() ? "/" :
511 StringUtil::EscapeJsonStringValue(eventInfos["LAST_FRAME"]));
512 }
513 if (info.faultLogType != FaultLogType::ADDR_SANITIZER) {
514 sysEvent.SetEventValue("FINGERPRINT", eventInfos["fingerPrint"]);
515 }
516 }
517
OnEvent(std::shared_ptr<Event> &event)518 bool Faultlogger::OnEvent(std::shared_ptr<Event> &event)
519 {
520 if (!hasInit_ || event == nullptr) {
521 return false;
522 }
523 if (event->eventName_ != "JS_ERROR" && event->eventName_ != "RUST_PANIC"
524 && event->eventName_ != "ADDR_SANITIZER") {
525 return true;
526 }
527 if (event->rawData_ == nullptr) {
528 return false;
529 }
530 auto sysEvent = std::static_pointer_cast<SysEvent>(event);
531 HIVIEW_LOGI("Receive %{public}s Event:%{public}s.", event->eventName_.c_str(), sysEvent->AsJsonStr().c_str());
532 FaultLogInfo info = FillFaultLogInfo(*sysEvent);
533 if (info.faultLogType == FaultLogType::ADDR_SANITIZER && info.summary.empty()) {
534 HIVIEW_LOGI("Skip non address_sanitizer request.");
535 return true;
536 }
537 AddFaultLog(info);
538 UpdateSysEvent(*sysEvent, info);
539 if (info.faultLogType == FaultLogType::JS_CRASH) {
540 ReportJsErrorToAppEvent(sysEvent);
541 }
542 if (info.faultLogType == FaultLogType::ADDR_SANITIZER) {
543 ReportSanitizerToAppEvent(sysEvent);
544 }
545 return true;
546 }
547
CanProcessEvent(std::shared_ptr<Event> event)548 bool Faultlogger::CanProcessEvent(std::shared_ptr<Event> event)
549 {
550 return true;
551 }
552
FillHilog(const std::string &hilogStr, Json::Value &hilog) const553 void Faultlogger::FillHilog(const std::string &hilogStr, Json::Value &hilog) const
554 {
555 if (hilogStr.empty()) {
556 HIVIEW_LOGE("Get hilog is empty");
557 return;
558 }
559 std::stringstream logStream(hilogStr);
560 std::string oneLine;
561 for (int count = 0; count < REPORT_HILOG_LINE && getline(logStream, oneLine); count++) {
562 hilog.append(oneLine);
563 }
564 }
565
ReportJsErrorToAppEvent(std::shared_ptr<SysEvent> sysEvent) const566 void Faultlogger::ReportJsErrorToAppEvent(std::shared_ptr<SysEvent> sysEvent) const
567 {
568 std::string summary = StringUtil::UnescapeJsonStringValue(sysEvent->GetEventValue("SUMMARY"));
569 HIVIEW_LOGD("ReportAppEvent:summary:%{public}s.", summary.c_str());
570
571 Json::Value params;
572 params["time"] = sysEvent->happenTime_;
573 params["crash_type"] = "JsError";
574 std::string foreground = sysEvent->GetEventValue("FOREGROUND");
575 if (foreground == "Yes") {
576 params["foreground"] = true;
577 } else {
578 params["foreground"] = false;
579 }
580 Json::Value externalLog(Json::arrayValue);
581 std::string logPath = sysEvent->GetEventValue("LOG_PATH");
582 if (!logPath.empty()) {
583 externalLog.append(logPath);
584 }
585 params["external_log"] = externalLog;
586 params["bundle_version"] = sysEvent->GetEventValue("VERSION");
587 params["bundle_name"] = sysEvent->GetEventValue("PACKAGE_NAME");
588 params["pid"] = sysEvent->GetPid();
589 params["uid"] = sysEvent->GetUid();
590 params["uuid"] = sysEvent->GetEventValue("FINGERPRINT");
591 params["app_running_unique_id"] = sysEvent->GetEventValue("APP_RUNNING_UNIQUE_ID");
592 FillJsErrorParams(summary, params);
593 std::string log;
594 Json::Value hilog(Json::arrayValue);
595 GetHilog(sysEvent->GetPid(), log);
596 FillHilog(log, hilog);
597 params["hilog"] = hilog;
598 std::string paramsStr = Json::FastWriter().write(params);
599 HIVIEW_LOGD("ReportAppEvent: uid:%{public}d, json:%{public}s.",
600 sysEvent->GetUid(), paramsStr.c_str());
601 #ifdef UNITTEST
602 std::string outputFilePath = "/data/test_jsError_info";
603 if (!FileUtil::FileExists(outputFilePath)) {
604 int fd = TEMP_FAILURE_RETRY(open(outputFilePath.c_str(), O_CREAT | O_RDWR | O_APPEND, DEFAULT_LOG_FILE_MODE));
605 if (fd != -1) {
606 close(fd);
607 }
608 }
609 FileUtil::SaveStringToFile(outputFilePath, paramsStr, false);
610 #else
611 EventPublish::GetInstance().PushEvent(sysEvent->GetUid(), APP_CRASH_TYPE, HiSysEvent::EventType::FAULT, paramsStr);
612 #endif
613 }
614
ReportSanitizerToAppEvent(std::shared_ptr<SysEvent> sysEvent) const615 void Faultlogger::ReportSanitizerToAppEvent(std::shared_ptr<SysEvent> sysEvent) const
616 {
617 std::string summary = StringUtil::UnescapeJsonStringValue(sysEvent->GetEventValue("SUMMARY"));
618 HIVIEW_LOGD("ReportSanitizerAppEvent:summary:%{public}s.", summary.c_str());
619
620 Json::Value params;
621 params["time"] = sysEvent->GetEventValue("HAPPEN_TIME");
622 params["type"] = sysEvent->GetEventValue("REASON");
623 Json::Value externalLog(Json::arrayValue);
624 std::string logPath = sysEvent->GetEventValue("LOG_PATH");
625 if (!logPath.empty()) {
626 externalLog.append(logPath);
627 }
628 params["external_log"] = externalLog;
629 params["bundle_version"] = sysEvent->GetEventValue("VERSION");
630 params["bundle_name"] = sysEvent->GetEventValue("MODULE");
631 params["pid"] = sysEvent->GetPid();
632 params["uid"] = sysEvent->GetUid();
633 FillJsErrorParams(summary, params);
634 std::string paramsStr = Json::FastWriter().write(params);
635 HIVIEW_LOGD("ReportSanitizerAppEvent: uid:%{public}d, json:%{public}s.",
636 sysEvent->GetUid(), paramsStr.c_str());
637 EventPublish::GetInstance().PushEvent(sysEvent->GetUid(), "ADDR_SANITIZER",
638 HiSysEvent::EventType::FAULT, paramsStr);
639 }
640
ReadyToLoad()641 bool Faultlogger::ReadyToLoad()
642 {
643 return true;
644 }
645
OnLoad()646 void Faultlogger::OnLoad()
647 {
648 mgr_ = std::make_unique<FaultLogManager>(GetHiviewContext()->GetSharedWorkLoop());
649 mgr_->Init();
650 hasInit_ = true;
651 workLoop_ = GetHiviewContext()->GetSharedWorkLoop();
652 #ifndef UNITTEST
653 FaultloggerAdapter::StartService(this);
654
655 // some crash happened before hiview start, ensure every crash event is added into eventdb
656 if (workLoop_ != nullptr) {
657 auto task = [this] {
658 StartBootScan();
659 };
660 workLoop_->AddTimerEvent(nullptr, nullptr, task, 10, false); // delay 10 seconds
661 }
662 #endif
663 }
664
AddFaultLog(FaultLogInfo& info)665 void Faultlogger::AddFaultLog(FaultLogInfo& info)
666 {
667 if (!hasInit_) {
668 return;
669 }
670
671 AddFaultLogIfNeed(info, nullptr);
672 }
673
GetFaultLogInfo(const std::string &logPath)674 std::unique_ptr<FaultLogInfo> Faultlogger::GetFaultLogInfo(const std::string &logPath)
675 {
676 if (!hasInit_) {
677 return nullptr;
678 }
679
680 auto info = std::make_unique<FaultLogInfo>(FaultLogger::ParseFaultLogInfoFromFile(logPath));
681 info->logPath = logPath;
682 return info;
683 }
684
QuerySelfFaultLog(int32_t id, int32_t pid, int32_t faultType, int32_t maxNum)685 std::unique_ptr<FaultLogQueryResultInner> Faultlogger::QuerySelfFaultLog(int32_t id,
686 int32_t pid, int32_t faultType, int32_t maxNum)
687 {
688 if (!hasInit_) {
689 return nullptr;
690 }
691
692 if ((faultType < FaultLogType::ALL) || (faultType > FaultLogType::APP_FREEZE)) {
693 HIVIEW_LOGW("Unsupported fault type");
694 return nullptr;
695 }
696
697 if (maxNum < 0 || maxNum > MAX_QUERY_NUM) {
698 maxNum = MAX_QUERY_NUM;
699 }
700
701 std::string name = "";
702 if (id >= MIN_APP_UID) {
703 name = GetApplicationNameById(id);
704 }
705
706 if (name.empty()) {
707 name = CommonUtils::GetProcNameByPid(pid);
708 }
709 return std::make_unique<FaultLogQueryResultInner>(mgr_->GetFaultInfoList(name, id, faultType, maxNum));
710 }
711
RemoveHilogFromFaultlog(const std::string &logPath, int32_t faultType) const712 void Faultlogger::RemoveHilogFromFaultlog(const std::string &logPath, int32_t faultType) const
713 {
714 std::ifstream logReadFile(logPath);
715 std::string readContent(std::istreambuf_iterator<char>(logReadFile), (std::istreambuf_iterator<char>()));
716 if (faultType == FaultLogType::CPP_CRASH) {
717 size_t pos = readContent.find("HiLog:");
718 if (pos == std::string::npos) {
719 HIVIEW_LOGW("No Hilog Found In Crash Log");
720 return;
721 }
722 readContent.resize(pos);
723 } else if (faultType == FaultLogType::APP_FREEZE) {
724 size_t posStart = readContent.find("catcher cmd: hilog");
725 size_t posEnd = readContent.find("catcher cmd: hidumper --cpuusage", posStart);
726 if (posStart == std::string::npos || posEnd == std::string::npos) {
727 HIVIEW_LOGW("No Hilog Found In Freeze Log");
728 return;
729 }
730 readContent.erase(posStart, posEnd - posStart);
731 }
732 std::ofstream logWriteFile(logPath);
733 logWriteFile << readContent;
734 logWriteFile.close();
735 }
736
AddFaultLogIfNeed(FaultLogInfo& info, std::shared_ptr<Event> event)737 void Faultlogger::AddFaultLogIfNeed(FaultLogInfo& info, std::shared_ptr<Event> event)
738 {
739 if ((info.faultLogType <= FaultLogType::ALL) || (info.faultLogType > FaultLogType::ADDR_SANITIZER)) {
740 HIVIEW_LOGW("Unsupported fault type");
741 return;
742 }
743 HIVIEW_LOGI("Start saving Faultlog of Process:%{public}d, Name:%{public}s, Reason:%{public}s.",
744 info.pid, info.module.c_str(), info.reason.c_str());
745 info.sectionMap["PROCESS_NAME"] = info.module; // save process name
746 // Non system processes use UID to pass events to applications
747 bool isSystemProcess = IsSystemProcess(info.module, info.id);
748 if (!isSystemProcess) {
749 std::string appName = GetApplicationNameById(info.id);
750 if (!appName.empty()) {
751 info.module = appName; // if bundle name is not empty, replace module name by it.
752 }
753 }
754
755 HIVIEW_LOGD("nameProc %{public}s", info.module.c_str());
756 if ((info.module.empty()) || (!IsModuleNameValid(info.module))) {
757 HIVIEW_LOGW("Invalid module name %{public}s", info.module.c_str());
758 return;
759 }
760 AddPublicInfo(info);
761 // Internal reserved fields, avoid illegal privilege escalation to access files
762 info.sectionMap.erase("APPEND_ORIGIN_LOG");
763 if (info.faultLogType == FaultLogType::CPP_CRASH) {
764 AddCppCrashInfo(info);
765 } else if (info.faultLogType == FaultLogType::APP_FREEZE) {
766 info.sectionMap["STACK"] = GetThreadStack(info.logPath, info.pid);
767 }
768
769 mgr_->SaveFaultLogToFile(info);
770 if (info.faultLogType != FaultLogType::JS_CRASH && info.faultLogType != FaultLogType::RUST_PANIC
771 && info.faultLogType != FaultLogType::ADDR_SANITIZER) {
772 mgr_->SaveFaultInfoToRawDb(info);
773 }
774 HIVIEW_LOGI("\nSave Faultlog of Process:%{public}d\n"
775 "ModuleName:%{public}s\n"
776 "Reason:%{public}s\n"
777 "Summary:%{public}s\n",
778 info.pid,
779 info.module.c_str(),
780 info.reason.c_str(),
781 info.summary.c_str());
782
783 if (!isSystemProcess && info.faultLogType == FaultLogType::CPP_CRASH) {
784 CheckFaultLogAsync(info);
785 ReportCppCrashToAppEvent(info);
786 } else if (!isSystemProcess && info.faultLogType == FaultLogType::APP_FREEZE) {
787 ReportAppFreezeToAppEvent(info);
788 }
789
790 if (IsFaultLogLimit()) {
791 RemoveHilogFromFaultlog(info.logPath, info.faultLogType);
792 }
793 }
794
OnUnorderedEvent(const Event &msg)795 void Faultlogger::OnUnorderedEvent(const Event &msg)
796 {
797 }
798
GetListenerName()799 std::string Faultlogger::GetListenerName()
800 {
801 return "FaultLogger";
802 }
803
StartBootScan()804 void Faultlogger::StartBootScan()
805 {
806 std::vector<std::string> files;
807 time_t now = time(nullptr);
808 FileUtil::GetDirFiles(TEMP_LOG_PATH, files);
809 for (const auto& file : files) {
810 // if file type is not cppcrash, skip!
811 if (file.find("cppcrash") == std::string::npos) {
812 HIVIEW_LOGI("Skip this file(%{public}s) that the type is not cppcrash.", file.c_str());
813 continue;
814 }
815 time_t lastAccessTime = GetFileLastAccessTimeStamp(file);
816 if ((now > lastAccessTime) && (now - lastAccessTime > FORTYEIGHT_HOURS)) {
817 HIVIEW_LOGI("Skip this file(%{public}s) that were created 48 hours ago.", file.c_str());
818 continue;
819 }
820 auto info = ParseFaultLogInfoFromFile(file, true);
821 if (info.summary.find("#00") == std::string::npos) {
822 HIVIEW_LOGI("Skip this file(%{public}s) which stack is empty.", file.c_str());
823 HiSysEventWrite(HiSysEvent::Domain::RELIABILITY, "CPP_CRASH_NO_LOG", HiSysEvent::EventType::FAULT,
824 "PID", info.pid,
825 "UID", info.id,
826 "PROCESS_NAME", info.module,
827 "HAPPEN_TIME", std::to_string(info.time)
828 );
829 if (remove(file.c_str()) != 0) {
830 HIVIEW_LOGE("Failed to remove file(%{public}s) which stack is empty", file.c_str());
831 }
832 continue;
833 }
834 if (mgr_->IsProcessedFault(info.pid, info.id, info.faultLogType)) {
835 HIVIEW_LOGI("Skip processed fault.(%{public}d:%{public}d) ", info.pid, info.id);
836 continue;
837 }
838 AddFaultLogIfNeed(info, nullptr);
839 }
840 }
841
ReportCppCrashToAppEvent(const FaultLogInfo& info) const842 void Faultlogger::ReportCppCrashToAppEvent(const FaultLogInfo& info) const
843 {
844 std::string stackInfo;
845 GetStackInfo(info, stackInfo);
846 if (stackInfo.length() == 0) {
847 HIVIEW_LOGE("stackInfo is empty");
848 return;
849 }
850 HIVIEW_LOGI("report cppcrash to appevent, pid:%{public}d len:%{public}zu", info.pid, stackInfo.length());
851 #ifdef UNIT_TEST
852 std::string outputFilePath = "/data/test_cppcrash_info_" + std::to_string(info.pid);
853 std::ofstream outFile(outputFilePath);
854 outFile << stackInfo << std::endl;
855 outFile.close();
856 #endif
857 EventPublish::GetInstance().PushEvent(info.id, APP_CRASH_TYPE, HiSysEvent::EventType::FAULT, stackInfo);
858 }
859
GetStackInfo(const FaultLogInfo& info, std::string& stackInfo) const860 void Faultlogger::GetStackInfo(const FaultLogInfo& info, std::string& stackInfo) const
861 {
862 if (info.pipeFd == nullptr || *(info.pipeFd) == -1) {
863 HIVIEW_LOGE("invalid fd");
864 return;
865 }
866 ssize_t nread = -1;
867 char *buffer = new char[MAX_PIPE_SIZE];
868 nread = TEMP_FAILURE_RETRY(read(*info.pipeFd, buffer, MAX_PIPE_SIZE));
869 if (nread <= 0) {
870 HIVIEW_LOGE("read pipe failed");
871 delete []buffer;
872 return;
873 }
874 std::string stackInfoOriginal(buffer, nread);
875 delete []buffer;
876 Json::Reader reader;
877 Json::Value stackInfoObj;
878 if (!reader.parse(stackInfoOriginal, stackInfoObj)) {
879 HIVIEW_LOGE("parse stackInfo failed");
880 return;
881 }
882 stackInfoObj["bundle_name"] = info.module;
883 Json::Value externalLog;
884 externalLog.append(info.logPath);
885 stackInfoObj["external_log"] = externalLog;
886 if (info.sectionMap.count("VERSION") == 1) {
887 stackInfoObj["bundle_version"] = info.sectionMap.at("VERSION");
888 }
889 if (info.sectionMap.count("FOREGROUND") == 1) {
890 stackInfoObj["foreground"] = (info.sectionMap.at("FOREGROUND") == "Yes") ? true : false;
891 }
892 if (info.sectionMap.count("FINGERPRINT") == 1) {
893 stackInfoObj["uuid"] = info.sectionMap.at("FINGERPRINT");
894 }
895 if (info.sectionMap.count("HILOG") == 1) {
896 Json::Value hilog(Json::arrayValue);
897 auto hilogStr = info.sectionMap.at("HILOG");
898 FillHilog(hilogStr, hilog);
899 stackInfoObj["hilog"] = hilog;
900 }
901 stackInfo.append(Json::FastWriter().write(stackInfoObj));
902 }
903
DoGetHilogProcess(int32_t pid, int writeFd) const904 int Faultlogger::DoGetHilogProcess(int32_t pid, int writeFd) const
905 {
906 HIVIEW_LOGD("Start do get hilog process, pid:%{public}d", pid);
907 if (writeFd < 0 || dup2(writeFd, STDOUT_FILENO) == -1 ||
908 dup2(writeFd, STDERR_FILENO) == -1) {
909 HIVIEW_LOGE("dup2 writeFd fail");
910 return -1;
911 }
912
913 int ret = -1;
914 ret = execl("/system/bin/hilog", "hilog", "-z", "1000", "-P", std::to_string(pid).c_str(), nullptr);
915 if (ret < 0) {
916 HIVIEW_LOGE("execl %{public}d, errno: %{public}d", ret, errno);
917 return ret;
918 }
919 return 0;
920 }
921
GetHilog(int32_t pid, std::string& log) const922 bool Faultlogger::GetHilog(int32_t pid, std::string& log) const
923 {
924 int fds[2] = {-1, -1}; // 2: one read pipe, one write pipe
925 if (pipe(fds) != 0) {
926 HIVIEW_LOGE("Failed to create pipe for get log.");
927 return false;
928 }
929 int childPid = fork();
930 if (childPid < 0) {
931 HIVIEW_LOGE("fork fail");
932 return false;
933 } else if (childPid == 0) {
934 syscall(SYS_close, fds[0]);
935 int rc = DoGetHilogProcess(pid, fds[1]);
936 syscall(SYS_close, fds[1]);
937 _exit(rc);
938 } else {
939 syscall(SYS_close, fds[1]);
940 // read log from fds[0]
941 while (true) {
942 char buffer[READ_HILOG_BUFFER_SIZE] = {0};
943 ssize_t nread = TEMP_FAILURE_RETRY(read(fds[0], buffer, sizeof(buffer) - 1));
944 if (nread <= 0) {
945 HIVIEW_LOGI("read hilog finished");
946 break;
947 }
948 log.append(buffer);
949 }
950 syscall(SYS_close, fds[0]);
951
952 if (TEMP_FAILURE_RETRY(waitpid(childPid, nullptr, 0)) != childPid) {
953 HIVIEW_LOGE("waitpid fail, pid: %{public}d, errno: %{public}d", childPid, errno);
954 return false;
955 }
956 HIVIEW_LOGI("get hilog waitpid %{public}d success", childPid);
957 return true;
958 }
959 return false;
960 }
961
GetDightStrArr(const std::string& target)962 std::list<std::string> GetDightStrArr(const std::string& target)
963 {
964 std::list<std::string> ret;
965 std::string temp = "";
966 for (size_t i = 0, len = target.size(); i < len; i++) {
967 if (target[i] >= '0' && target[i] <= '9') {
968 temp += target[i];
969 continue;
970 }
971 if (temp.size() != 0) {
972 ret.push_back(temp);
973 temp = "";
974 }
975 }
976 if (temp.size() != 0) {
977 ret.push_back(temp);
978 }
979 ret.push_back("0");
980 return ret;
981 }
982
GetMemoryStrByPid(long pid) const983 std::string Faultlogger::GetMemoryStrByPid(long pid) const
984 {
985 if (pid <= 0) {
986 return "";
987 }
988 unsigned long long rss = 0; // statm col = 2 *4
989 unsigned long long vss = 0; // statm col = 1 *4
990 unsigned long long sysFreeMem = 0; // meminfo row=2
991 unsigned long long sysAvailMem = 0; // meminfo row=3
992 unsigned long long sysTotalMem = 0; // meminfo row=1
993 std::ifstream statmStream("/proc/" + std::to_string(pid) + "/statm");
994 if (statmStream) {
995 std::string statmLine;
996 std::getline(statmStream, statmLine);
997 HIVIEW_LOGI("/proc/%{public}ld/statm : %{public}s", pid, statmLine.c_str());
998 statmStream.close();
999 std::list<std::string> numStrArr = GetDightStrArr(statmLine);
1000 auto it = numStrArr.begin();
1001 unsigned long long multiples = 4;
1002 vss = multiples * std::stoull(*it);
1003 it++;
1004 rss = multiples * std::stoull(*it);
1005 HIVIEW_LOGI("GET FreezeJson rss=%{public}llu, vss=%{public}llu.", rss, vss);
1006 } else {
1007 HIVIEW_LOGE("Fail to open /proc/%{public}ld/statm", pid);
1008 }
1009
1010 std::ifstream meminfoStream("/proc/meminfo");
1011 if (meminfoStream) {
1012 std::string meminfoLine;
1013 std::getline(meminfoStream, meminfoLine);
1014 sysTotalMem = std::stoull(GetDightStrArr(meminfoLine).front());
1015 std::getline(meminfoStream, meminfoLine);
1016 sysFreeMem = std::stoull(GetDightStrArr(meminfoLine).front());
1017 std::getline(meminfoStream, meminfoLine);
1018 sysAvailMem = std::stoull(GetDightStrArr(meminfoLine).front());
1019 meminfoStream.close();
1020 HIVIEW_LOGI("GET FreezeJson sysFreeMem=%{public}llu, sysAvailMem=%{public}llu, sysTotalMem=%{public}llu.",
1021 sysFreeMem, sysAvailMem, sysTotalMem);
1022 } else {
1023 HIVIEW_LOGE("Fail to open /proc/meminfo");
1024 }
1025
1026 FreezeJsonMemory freezeJsonMemory = FreezeJsonMemory::Builder()
1027 .InitRss(rss)
1028 .InitVss(vss)
1029 .InitSysFreeMem(sysFreeMem)
1030 .InitSysAvailMem(sysAvailMem)
1031 .InitSysTotalMem(sysTotalMem)
1032 .Build();
1033 return freezeJsonMemory.JsonStr();
1034 }
1035
GetFreezeJsonCollector(const FaultLogInfo& info) const1036 FreezeJsonUtil::FreezeJsonCollector Faultlogger::GetFreezeJsonCollector(const FaultLogInfo& info) const
1037 {
1038 FreezeJsonUtil::FreezeJsonCollector collector = {0};
1039 std::string jsonFilePath = FreezeJsonUtil::GetFilePath(info.pid, info.id, info.time);
1040 if (!FileUtil::FileExists(jsonFilePath)) {
1041 HIVIEW_LOGE("Not Exist FreezeJsonFile: %{public}s.", jsonFilePath.c_str());
1042 return collector;
1043 }
1044 FreezeJsonUtil::LoadCollectorFromFile(jsonFilePath, collector);
1045 HIVIEW_LOGI("load FreezeJsonFile.");
1046 FreezeJsonUtil::DelFile(jsonFilePath);
1047
1048 FreezeJsonException exception = FreezeJsonException::Builder()
1049 .InitName(collector.stringId)
1050 .InitMessage(collector.message)
1051 .Build();
1052 collector.exception = exception.JsonStr();
1053
1054 std::list<std::string> hilogList;
1055 std::string hilogStr;
1056 GetHilog(collector.pid, hilogStr);
1057 if (hilogStr.length() == 0) {
1058 HIVIEW_LOGE("Get FreezeJson hilog is empty!");
1059 } else {
1060 std::stringstream hilogStream(hilogStr);
1061 std::string oneLine;
1062 int count = 0;
1063 while (++count <= REPORT_HILOG_LINE && std::getline(hilogStream, oneLine)) {
1064 hilogList.push_back(StringUtil::EscapeJsonStringValue(oneLine));
1065 }
1066 }
1067 collector.hilog = FreezeJsonUtil::GetStrByList(hilogList);
1068
1069 collector.memory = GetMemoryStrByPid(collector.pid);
1070
1071 if (info.sectionMap.count("FOREGROUND") == 1) {
1072 std::string foreground = info.sectionMap.at("FOREGROUND");
1073 collector.foreground = (foreground == "Yes");
1074 }
1075
1076 if (info.sectionMap.count("VERSION") == 1) {
1077 collector.version = info.sectionMap.at("VERSION");
1078 }
1079
1080 if (info.sectionMap.count("FINGERPRINT") == 1) {
1081 collector.uuid = info.sectionMap.at("FINGERPRINT");
1082 }
1083
1084 return collector;
1085 }
1086
ReportAppFreezeToAppEvent(const FaultLogInfo& info) const1087 void Faultlogger::ReportAppFreezeToAppEvent(const FaultLogInfo& info) const
1088 {
1089 HIVIEW_LOGI("Start to report freezeJson !!!");
1090
1091 FreezeJsonUtil::FreezeJsonCollector collector = GetFreezeJsonCollector(info);
1092 std::list<std::string> externalLogList;
1093 externalLogList.push_back(info.logPath);
1094 std::string externalLog = FreezeJsonUtil::GetStrByList(externalLogList);
1095
1096 FreezeJsonParams freezeJsonParams = FreezeJsonParams::Builder()
1097 .InitTime(collector.timestamp)
1098 .InitUuid(collector.uuid)
1099 .InitFreezeType("AppFreeze")
1100 .InitForeground(collector.foreground)
1101 .InitBundleVersion(collector.version)
1102 .InitBundleName(collector.package_name)
1103 .InitProcessName(collector.process_name)
1104 .InitExternalLog(externalLog)
1105 .InitPid(collector.pid)
1106 .InitUid(collector.uid)
1107 .InitAppRunningUniqueId(collector.appRunningUniqueId)
1108 .InitException(collector.exception)
1109 .InitHilog(collector.hilog)
1110 .InitEventHandler(collector.event_handler)
1111 .InitEventHandlerSize3s(collector.event_handler_3s_size)
1112 .InitEventHandlerSize6s(collector.event_handler_6s_size)
1113 .InitPeerBinder(collector.peer_binder)
1114 .InitThreads(collector.stack)
1115 .InitMemory(collector.memory)
1116 .Build();
1117 EventPublish::GetInstance().PushEvent(info.id, APP_FREEZE_TYPE,
1118 HiSysEvent::EventType::FAULT, freezeJsonParams.JsonStr());
1119 HIVIEW_LOGI("Report FreezeJson Successfully!");
1120 }
1121
1122 /*
1123 * return value: 0 means fault log invalid; 1 means fault log valid.
1124 */
CheckFaultLog(FaultLogInfo info)1125 bool Faultlogger::CheckFaultLog(FaultLogInfo info)
1126 {
1127 int32_t err = CrashExceptionCode::CRASH_ESUCCESS;
1128 if (!CheckFaultSummaryValid(info.summary)) {
1129 err = CrashExceptionCode::CRASH_LOG_ESUMMARYLOS;
1130 }
1131 ReportCrashException(info.module, info.pid, info.id, err);
1132
1133 return (err == CrashExceptionCode::CRASH_ESUCCESS);
1134 }
1135
CheckFaultLogAsync(const FaultLogInfo& info)1136 void Faultlogger::CheckFaultLogAsync(const FaultLogInfo& info)
1137 {
1138 if (workLoop_ != nullptr) {
1139 auto task = [this, info] {
1140 CheckFaultLog(info);
1141 };
1142 workLoop_->AddTimerEvent(nullptr, nullptr, task, 0, false);
1143 }
1144 }
1145 } // namespace HiviewDFX
1146 } // namespace OHOS
1147
1148