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 #include "faultlog_manager_service.h"
17
18 #include "common_utils.h"
19 #include "hiview_logger.h"
20 #include "faultlog_bundle_util.h"
21 #include "faultlog_dump.h"
22 #include "faultlog_processor_factory.h"
23 #include "parameters.h"
24
25 namespace OHOS {
26 namespace HiviewDFX {
27 DEFINE_LOG_LABEL(0xD002D11, "Faultlogger");
28 namespace {
29 constexpr int32_t MAX_QUERY_NUM = 100;
30 constexpr int MIN_APP_UID = 10000;
31 constexpr int MAX_APPLICATION_ENABLE = 20;
32 constexpr uint64_t DEFAULT_DURATION = 7;
33 constexpr uint64_t DAYS_TO_MILLISEC = 24 * 60 * 60;
34 } // namespace
35
Dump(int fd,const std::vector<std::string> & cmds)36 void FaultLogManagerService::Dump(int fd, const std::vector<std::string>& cmds)
37 {
38 if (!faultLogManager_) {
39 return;
40 }
41 FaultLogDump faultLogDump(fd, faultLogManager_);
42 faultLogDump.DumpByCommands(cmds);
43 }
44
AddFaultLog(FaultLogInfo & info)45 void FaultLogManagerService::AddFaultLog(FaultLogInfo& info)
46 {
47 if (!faultLogManager_) {
48 return;
49 }
50 FaultLogProcessorFactory factory;
51 auto processor = factory.CreateFaultLogProcessor(static_cast<FaultLogType>(info.faultLogType));
52 if (processor) {
53 processor->AddFaultLog(info, workLoop_, faultLogManager_);
54 }
55 }
56
QuerySelfFaultLog(int32_t id,int32_t pid,int32_t faultType,int32_t maxNum)57 std::unique_ptr<FaultLogQueryResultInner> FaultLogManagerService::QuerySelfFaultLog(int32_t id,
58 int32_t pid, int32_t faultType, int32_t maxNum)
59 {
60 if (!faultLogManager_) {
61 return nullptr;
62 }
63 if ((faultType < FaultLogType::ALL) || (faultType > FaultLogType::APP_FREEZE)) {
64 HIVIEW_LOGW("Unsupported fault type");
65 return nullptr;
66 }
67
68 if (maxNum < 0 || maxNum > MAX_QUERY_NUM) {
69 maxNum = MAX_QUERY_NUM;
70 }
71
72 std::string name;
73 if (id >= MIN_APP_UID) {
74 name = GetApplicationNameById(id);
75 }
76
77 if (name.empty()) {
78 name = CommonUtils::GetProcNameByPid(pid);
79 }
80 return std::make_unique<FaultLogQueryResultInner>(faultLogManager_->GetFaultInfoList(name, id, faultType, maxNum));
81 }
82
EnableGwpAsanGrayscale(bool alwaysEnabled,double sampleRate,double maxSimutaneousAllocations,int32_t duration,int32_t uid)83 bool FaultLogManagerService::EnableGwpAsanGrayscale(bool alwaysEnabled, double sampleRate,
84 double maxSimutaneousAllocations, int32_t duration, int32_t uid)
85 {
86 std::string bundleName = GetApplicationNameById(uid);
87 if (bundleName.empty()) {
88 HIVIEW_LOGE("Enable gwpAsanGrayscale failed, the bundleName is not exist");
89 return false;
90 }
91 HIVIEW_LOGD("EnableGwpAsanGrayscale success, bundleName: %{public}s, alwaysEnabled: %{public}d "
92 ", sampleRate: %{public}f, maxSimutaneousAllocations: %{public}f, duration: %{public}d",
93 bundleName.c_str(), alwaysEnabled, sampleRate, maxSimutaneousAllocations, duration);
94 std::string isEnable = system::GetParameter("gwp_asan.enable.app." + bundleName, "");
95 std::string appNumStr = system::GetParameter("gwp_asan.app_num", "0");
96 int appNum = 0;
97 std::stringstream ss(appNumStr);
98 if (!(ss >> appNum)) {
99 HIVIEW_LOGE("Invalid appNum value: %{public}s", appNumStr.c_str());
100 appNum = 0;
101 }
102 if (isEnable.empty() && appNum >= MAX_APPLICATION_ENABLE) {
103 HIVIEW_LOGE("Enable gwpAsanGrayscale failed, the maximum quantity exceeds 20");
104 return false;
105 }
106 if (isEnable.empty()) {
107 system::SetParameter("gwp_asan.app_num", std::to_string(appNum + 1));
108 }
109 int sampleRateInt = static_cast<int>(std::ceil(sampleRate));
110 int slotInt = static_cast<int>(std::ceil(maxSimutaneousAllocations));
111 std::string sample = std::to_string(sampleRateInt) + ":" + std::to_string(slotInt);
112 system::SetParameter("gwp_asan.enable.app." + bundleName, alwaysEnabled ? "true" : "false");
113 system::SetParameter("gwp_asan.sample.app." + bundleName, sample);
114
115 uint64_t beginTime = static_cast<uint64_t>(std::time(nullptr));
116 system::SetParameter("gwp_asan.gray_begin.app." + bundleName, std::to_string(beginTime));
117 system::SetParameter("gwp_asan.gray_days.app." + bundleName, std::to_string(duration));
118 return true;
119 }
120
DisableGwpAsanGrayscale(int32_t uid)121 void FaultLogManagerService::DisableGwpAsanGrayscale(int32_t uid)
122 {
123 std::string bundleName = GetApplicationNameById(uid);
124 if (bundleName.empty()) {
125 HIVIEW_LOGE("Disable gwpAsanGrayscale failed, the bundleName is not exist");
126 return;
127 }
128 system::SetParameter("gwp_asan.gray_begin.app." + bundleName, "");
129 system::SetParameter("gwp_asan.gray_days.app." + bundleName, "");
130 system::SetParameter("gwp_asan.enable.app." + bundleName, "");
131 system::SetParameter("gwp_asan.sample.app." + bundleName, "");
132 }
133
GetGwpAsanGrayscaleState(int32_t uid)134 uint32_t FaultLogManagerService::GetGwpAsanGrayscaleState(int32_t uid)
135 {
136 std::string bundleName = GetApplicationNameById(uid);
137 if (bundleName.empty()) {
138 HIVIEW_LOGE("Get gwpAsanGrayscale state failed, the bundleName is not exist");
139 return 0;
140 }
141 std::string beginTimeStr = system::GetParameter("gwp_asan.gray_begin.app." + bundleName, "0");
142 uint64_t beginTime = 0;
143 std::stringstream beginSs(beginTimeStr);
144 if (!(beginSs >> beginTime)) {
145 HIVIEW_LOGE("Invalid beginTime value: %{public}s", beginTimeStr.c_str());
146 return 0;
147 }
148
149 std::string durationStr = system::GetParameter("gwp_asan.gray_days.app." + bundleName, "7");
150 uint64_t durationDays = DEFAULT_DURATION;
151 std::stringstream durationSs(durationStr);
152 if (!(durationSs >> durationDays)) {
153 durationDays = DEFAULT_DURATION;
154 }
155
156 uint64_t now = static_cast<uint64_t>(std::time(nullptr));
157 if (now < beginTime) {
158 return 0;
159 }
160
161 uint64_t lastDays = (now - beginTime) / (DAYS_TO_MILLISEC);
162 return static_cast<uint32_t>(durationDays > lastDays ? durationDays - lastDays : 0);
163 }
164 } // namespace HiviewDFX
165 } // namespace OHOS
166