• 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 
16 #define LOG_TAG "HiViewFaultAdapter"
17 
18 #include "hiview_fault_adapter.h"
19 
20 #include <iomanip>
21 #include <sstream>
22 #include "log_print.h"
23 
24 namespace OHOS {
25 namespace DataShare {
26 namespace {
27     constexpr char DOMAIN[] = "DISTDATAMGR";
28     constexpr const char *EVENT_NAME = "DISTRIBUTED_DATA_SHARE_FAULT";
29     constexpr const size_t PARAMS_SIZE = 8;
30     // digits for milliseconds
31     constexpr uint8_t MILLSECOND_DIGIT = 3;
32 }
33 
ReportDataFault(const DataShareFaultInfo & faultInfo)34 void HiViewFaultAdapter::ReportDataFault(const DataShareFaultInfo &faultInfo)
35 {
36     auto now = std::chrono::system_clock::now();
37     auto t = std::chrono::system_clock::to_time_t(now);
38     std::stringstream ss;
39     ss << std::put_time(std::localtime(&t), "%F %T");
40     // get milliseconds
41     auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
42     ss << '.' << std::setfill('0') << std::setw(MILLSECOND_DIGIT) << ms.count();
43     auto time = ss.str();
44     HiSysEventParam faultTime = { .name = "FAULT_TIME", .t = HISYSEVENT_STRING,
45         .v = { .s = const_cast<char*>(time.c_str()) }, .arraySize = 0 };
46     HiSysEventParam faultType = { .name = "FAULT_TYPE", .t = HISYSEVENT_STRING,
47         .v = { .s = const_cast<char*>(faultInfo.faultType.c_str()) }, .arraySize = 0 };
48     HiSysEventParam bundleName = { .name = "BUNDLE_NAME", .t = HISYSEVENT_STRING,
49         .v = { .s = const_cast<char*>(faultInfo.bundleName.c_str()) }, .arraySize = 0 };
50     HiSysEventParam moduleName = { .name = "MODULE_NAME", .t = HISYSEVENT_STRING,
51         .v = { .s = const_cast<char*>(faultInfo.moduleName.c_str()) }, .arraySize = 0 };
52     HiSysEventParam storeName = { .name = "STORE_NAME", .t = HISYSEVENT_STRING,
53         .v = { .s = const_cast<char*>(faultInfo.storeName.c_str()) }, .arraySize = 0 };
54     HiSysEventParam businessType = { .name = "BUSINESS_TYPE", .t = HISYSEVENT_STRING,
55         .v = { .s = const_cast<char*>(faultInfo.businessType.c_str()) }, .arraySize = 0 };
56     HiSysEventParam errorCode = { .name = "ERROR_CODE", .t = HISYSEVENT_INT32,
57         .v = { .i32 = faultInfo.errorCode }, .arraySize = 0 };
58     HiSysEventParam appendix = { .name = "APPENDIX", .t = HISYSEVENT_STRING,
59         .v = { .s = const_cast<char*>(faultInfo.appendix.c_str()) }, .arraySize = 0 };
60     HiSysEventParam params[] = { faultTime, faultType, bundleName, moduleName,
61         storeName, businessType, errorCode, appendix };
62     int res = OH_HiSysEvent_Write(DOMAIN, EVENT_NAME, HISYSEVENT_FAULT, params, PARAMS_SIZE);
63     ZLOGI("OH_HiSysEvent_Write, res = %{public}d", res);
64 }
65 
GetCallingName(uint32_t callingTokenid)66 std::pair<std::string, int> HiViewFaultAdapter::GetCallingName(uint32_t callingTokenid)
67 {
68     std::string callingName;
69     auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callingTokenid);
70     int result = -1;
71     if (tokenType == Security::AccessToken::TOKEN_HAP) {
72         Security::AccessToken::HapTokenInfo tokenInfo;
73         result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callingTokenid, tokenInfo);
74         if (result == Security::AccessToken::RET_SUCCESS) {
75             callingName = tokenInfo.bundleName;
76         }
77     } else if (tokenType == Security::AccessToken::TOKEN_NATIVE || tokenType == Security::AccessToken::TOKEN_SHELL) {
78         Security::AccessToken::NativeTokenInfo tokenInfo;
79         result = Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(callingTokenid, tokenInfo);
80         if (result == Security::AccessToken::RET_SUCCESS) {
81             callingName = tokenInfo.processName;
82         }
83     } else {
84         ZLOGE("tokenType is invalid, tokenType:%{public}d, Tokenid:%{public}x", tokenType, callingTokenid);
85     }
86     return std::make_pair(callingName, result);
87 }
88 
Report(const std::string & timeoutAppendix,const std::chrono::milliseconds timeoutms)89 void TimeoutReport::Report(const std::string &timeoutAppendix, const std::chrono::milliseconds timeoutms)
90 {
91     auto end = std::chrono::steady_clock::now();
92     std::chrono::milliseconds duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
93     // Used to report DFX timeout faults
94     if (needFaultReport && duration > HiViewFaultAdapter::dfxTimeOutMs) {
95         DFXReport(duration);
96     }
97     // Used to report log timeout
98     if (duration > timeoutms) {
99         int64_t milliseconds = duration.count();
100         ZLOGE("over time when doing %{public}s, %{public}s, cost:%{public}" PRIi64 "ms",
101             dfxInfo.businessType.c_str(), timeoutAppendix.c_str(), milliseconds);
102     }
103 }
104 
Report(const std::string & user,uint32_t callingPid,int32_t appIndex,int32_t instanceId)105 void TimeoutReport::Report(const std::string &user, uint32_t callingPid, int32_t appIndex, int32_t instanceId)
106 {
107     auto end = std::chrono::steady_clock::now();
108     std::chrono::milliseconds duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
109     // Used to report DFX timeout faults
110     if (needFaultReport && duration > HiViewFaultAdapter::dfxTimeOutMs) {
111         DFXReport(duration);
112     }
113     // Used to report log timeout
114     if (duration > HiViewFaultAdapter::timeOutMs) {
115         int64_t milliseconds = duration.count();
116         std::string timeoutAppendix = "bundleName: " + dfxInfo.bundleName + ", user: " + user + ", callingPid: " +
117             std::to_string(callingPid);
118         if (!dfxInfo.storeName.empty()) {
119             timeoutAppendix += ", storeName: " + dfxInfo.storeName;
120         }
121         if (appIndex != -1) {
122             timeoutAppendix += ", appIndex: " + std::to_string(appIndex);
123         }
124         if (instanceId != -1) {
125             timeoutAppendix += ", instanceId: " + std::to_string(instanceId);
126         }
127         ZLOGE("over time when doing %{public}s, %{public}s, cost:%{public}" PRIi64 "ms",
128             dfxInfo.businessType.c_str(), timeoutAppendix.c_str(), milliseconds);
129     }
130 }
131 
DFXReport(const std::chrono::milliseconds & duration)132 void TimeoutReport::DFXReport(const std::chrono::milliseconds &duration)
133 {
134     int64_t milliseconds = duration.count();
135     std::string appendix = "callingName:" + HiViewFaultAdapter::GetCallingName(dfxInfo.callingTokenId).first;
136     appendix += ",cost:" + std::to_string(milliseconds) + "ms";
137     DataShareFaultInfo faultInfo{HiViewFaultAdapter::timeOut, dfxInfo.bundleName, dfxInfo.moduleName,
138         dfxInfo.storeName, dfxInfo.businessType, errorCode, appendix};
139     HiViewFaultAdapter::ReportDataFault(faultInfo);
140 }
141 }
142 }