1 /*
2 * Copyright (c) 2025 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 "faultlog_error_reporter.h"
16
17 #include <tuple>
18
19 #include "fcntl.h"
20
21 #include "constants.h"
22 #include "faultlog_hilog_helper.h"
23 #include "file_util.h"
24 #include "hiview_logger.h"
25 #include "hisysevent.h"
26 #include "string_util.h"
27 #include "time_util.h"
28 #include "event.h"
29 #include "event_publish.h"
30
31 namespace OHOS {
32 namespace HiviewDFX {
33 DEFINE_LOG_LABEL(0xD002D11, "Faultlogger");
34 using namespace FileUtil;
35 using namespace FaultlogHilogHelper;
36 using namespace FaultLogger;
37
38 namespace {
39 const char * const STACK_ERROR_MESSAGE = "Cannot get SourceMap info, dump raw stack:";
40 constexpr mode_t DEFAULT_LOG_FILE_MODE = 0644;
41
ParseErrorSummary(const std::string & summary)42 auto ParseErrorSummary(const std::string& summary)
43 {
44 std::string leftStr = StringUtil::GetLeftSubstr(summary, "Error message:");
45 std::string rightStr = StringUtil::GetRightSubstr(summary, "Error message:");
46 std::string name = StringUtil::GetRightSubstr(leftStr, "Error name:");
47 std::string stack = StringUtil::GetRightSubstr(rightStr, "Stacktrace:");
48 leftStr = StringUtil::GetLeftSubstr(rightStr, "Stacktrace:");
49 do {
50 if (leftStr.find("Error code:") != std::string::npos) {
51 leftStr = StringUtil::GetLeftSubstr(leftStr, "Error code:");
52 break;
53 }
54 if (leftStr.find("SourceCode:") != std::string::npos) {
55 leftStr = StringUtil::GetLeftSubstr(leftStr, "SourceCode:");
56 break;
57 }
58 } while (false);
59
60 return std::make_tuple(name, leftStr, stack);
61 }
62
FillErrorParams(const std::string & summary,Json::Value & params)63 void FillErrorParams(const std::string& summary, Json::Value& params)
64 {
65 Json::Value exception;
66 exception["name"] = "";
67 exception["message"] = "";
68 exception["stack"] = "";
69 if (!summary.empty()) {
70 auto [name, message, stack] = ParseErrorSummary(summary);
71 name.erase(name.find_last_not_of("\n") + 1);
72 message.erase(message.find_last_not_of("\n") + 1);
73 if (stack.size() > 1) {
74 stack.erase(0, 1);
75 if ((stack.size() >= strlen(STACK_ERROR_MESSAGE)) &&
76 (strcmp(STACK_ERROR_MESSAGE, stack.substr(0, strlen(STACK_ERROR_MESSAGE)).c_str()) == 0)) {
77 stack.erase(0, strlen(STACK_ERROR_MESSAGE) + 1);
78 }
79 }
80 exception["name"] = name;
81 exception["message"] = message;
82 exception["stack"] = stack;
83 }
84 params["exception"] = exception;
85 }
86 } // namespace
87
ReportErrorToAppEvent(std::shared_ptr<SysEvent> sysEvent,const std::string & type,const std::string & outputFilePath) const88 void FaultLogErrorReporter::ReportErrorToAppEvent(std::shared_ptr<SysEvent> sysEvent, const std::string& type,
89 const std::string& outputFilePath) const
90 {
91 std::string summary = StringUtil::UnescapeJsonStringValue(sysEvent->GetEventValue(FaultKey::SUMMARY));
92 HIVIEW_LOGD("ReportAppEvent:summary:%{public}s.", summary.c_str());
93
94 Json::Value params;
95 params["time"] = sysEvent->happenTime_;
96 params["crash_type"] = type;
97 params["foreground"] = sysEvent->GetEventValue(FaultKey::FOREGROUND) == "Yes";
98 Json::Value externalLog(Json::arrayValue);
99 std::string logPath = sysEvent->GetEventValue(FaultKey::LOG_PATH);
100 if (!logPath.empty()) {
101 externalLog.append(logPath);
102 }
103 params["external_log"] = externalLog;
104 params["bundle_version"] = sysEvent->GetEventValue(FaultKey::MODULE_VERSION);
105 params["bundle_name"] = sysEvent->GetEventValue(FaultKey::PACKAGE_NAME);
106 params["pid"] = sysEvent->GetPid();
107 params["uid"] = sysEvent->GetUid();
108 params["uuid"] = sysEvent->GetEventValue(FaultKey::FINGERPRINT);
109 params["app_running_unique_id"] = sysEvent->GetEventValue("APP_RUNNING_UNIQUE_ID");
110 FillErrorParams(summary, params);
111 std::string log = GetHilogByPid(sysEvent->GetPid());
112 params["hilog"] = ParseHilogToJson(log);
113 std::string paramsStr = Json::FastWriter().write(params);
114 HIVIEW_LOGD("ReportAppEvent: uid:%{public}d, json:%{public}s.",
115 sysEvent->GetUid(), paramsStr.c_str());
116 #ifdef UNITTEST
117 if (!FileUtil::FileExists(outputFilePath)) {
118 int fd = TEMP_FAILURE_RETRY(open(outputFilePath.c_str(), O_CREAT | O_RDWR | O_APPEND, DEFAULT_LOG_FILE_MODE));
119 if (fd != -1) {
120 uint64_t ownerTag = fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, LOG_DOMAIN);
121 fdsan_exchange_owner_tag(fd, 0, ownerTag);
122 fdsan_close_with_tag(fd, ownerTag);
123 }
124 }
125 FileUtil::SaveStringToFile(outputFilePath, paramsStr, false);
126 #else
127 EventPublish::GetInstance().PushEvent(sysEvent->GetUid(), APP_CRASH_TYPE, HiSysEvent::EventType::FAULT, paramsStr);
128 #endif
129 }
130 } // namespace HiviewDFX
131 } // namespace OHOS
132