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("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