• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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