1 /*
2 * Copyright (c) 2023-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 "appfreeze_manager.h"
16
17 #include <fcntl.h>
18 #include <sys/time.h>
19 #include <sys/wait.h>
20 #include <sys/types.h>
21 #include <sys/syscall.h>
22 #include <sys/stat.h>
23 #include <fstream>
24
25 #include "backtrace_local.h"
26 #include "faultloggerd_client.h"
27 #include "file_ex.h"
28 #include "ffrt.h"
29 #include "dfx_dump_catcher.h"
30 #include "directory_ex.h"
31 #include "hisysevent.h"
32 #include "hitrace_meter.h"
33 #include "parameter.h"
34 #include "parameters.h"
35 #include "singleton.h"
36 #include "res_sched_util.h"
37 #include "app_mgr_client.h"
38 #include "hilog_tag_wrapper.h"
39 #include "time_util.h"
40 #ifdef ABILITY_RUNTIME_HITRACE_ENABLE
41 #include "hitrace/hitracechain.h"
42 #endif
43 #include "appfreeze_cpu_freq_manager.h"
44
45 namespace OHOS {
46 namespace AppExecFwk {
47 namespace {
48 constexpr char EVENT_UID[] = "UID";
49 constexpr char EVENT_PID[] = "PID";
50 constexpr char EVENT_TID[] = "TID";
51 constexpr char EVENT_INPUT_ID[] = "INPUT_ID";
52 constexpr char EVENT_MESSAGE[] = "MSG";
53 constexpr char EVENT_PACKAGE_NAME[] = "PACKAGE_NAME";
54 constexpr char EVENT_PROCESS_NAME[] = "PROCESS_NAME";
55 constexpr char EVENT_STACK[] = "STACK";
56 constexpr char BINDER_INFO[] = "BINDER_INFO";
57 constexpr char APP_RUNNING_UNIQUE_ID[] = "APP_RUNNING_UNIQUE_ID";
58 constexpr char FREEZE_MEMORY[] = "FREEZE_MEMORY";
59 constexpr char FREEZE_INFO_PATH[] = "FREEZE_INFO_PATH";
60 #ifdef ABILITY_RUNTIME_HITRACE_ENABLE
61 constexpr char EVENT_TRACE_ID[] = "HITRACE_ID";
62 constexpr char EVENT_SPAN_ID[] = "SPAN_ID";
63 constexpr char EVENT_PARENT_SPAN_ID[] = "PARENT_SPAN_ID";
64 constexpr char EVENT_TRACE_FLAG[] = "TRACE_FLAG";
65 constexpr char EVENT_APPFREEZE_TYPE[] = "appfreeze";
66 constexpr char EVENT_SYSFREEZE_TYPE[] = "sysfreeze";
67 constexpr int32_t CHARACTER_WIDTH = 2;
68 #endif
69
70 constexpr int MAX_LAYER = 8;
71 constexpr int FREEZEMAP_SIZE_MAX = 20;
72 constexpr int FREEZE_TIME_LIMIT = 60000;
73 static constexpr uint8_t ARR_SIZE = 7;
74 static constexpr uint8_t DECIMAL = 10;
75 static constexpr uint8_t FREE_ASYNC_INDEX = 6;
76 static constexpr uint16_t FREE_ASYNC_MAX = 1000;
77 static constexpr int64_t NANOSECONDS = 1000000000; // NANOSECONDS mean 10^9 nano second
78 static constexpr int64_t MICROSECONDS = 1000000; // MICROSECONDS mean 10^6 millias second
79 static constexpr int DUMP_STACK_FAILED = -1;
80 static constexpr int DUMP_KERNEL_STACK_SUCCESS = 1;
81 constexpr uint64_t SEC_TO_MILLISEC = 1000;
82 constexpr uint32_t BUFFER_SIZE = 1024;
83 const std::string LOG_FILE_PATH = "data/log/eventlog";
84 static bool g_betaVersion = OHOS::system::GetParameter("const.logsystem.versiontype", "unknown") == "beta";
85 static bool g_overseaVersion = OHOS::system::GetParameter("const.global.region", "CN") != "CN";
86 static bool g_developMode = (OHOS::system::GetParameter("persist.hiview.leak_detector", "unknown") == "enable") ||
87 (OHOS::system::GetParameter("persist.hiview.leak_detector", "unknown") == "true");
88 }
89 static constexpr const char *const TWELVE_BIG_CPU_CUR_FREQ = "/sys/devices/system/cpu/cpufreq/policy2/scaling_cur_freq";
90 static constexpr const char *const TWELVE_BIG_CPU_MAX_FREQ = "/sys/devices/system/cpu/cpufreq/policy2/scaling_max_freq";
91 static constexpr const char *const TWELVE_MID_CPU_CUR_FREQ = "/sys/devices/system/cpu/cpufreq/policy1/scaling_cur_freq";
92 static constexpr const char *const TWELVE_MID_CPU_MAX_FREQ = "/sys/devices/system/cpu/cpufreq/policy1/scaling_max_freq";
93 const static std::set<std::string> HALF_EVENT_CONFIGS = {"UI_BLOCK_3S", "THREAD_BLOCK_3S", "BUSSNESS_THREAD_BLOCK_3S",
94 "LIFECYCLE_HALF_TIMEOUT", "LIFECYCLE_HALF_TIMEOUT_WARNING"};
95 static constexpr int PERF_TIME = 60000;
96 std::shared_ptr<AppfreezeManager> AppfreezeManager::instance_ = nullptr;
97 ffrt::mutex AppfreezeManager::singletonMutex_;
98 ffrt::mutex AppfreezeManager::freezeMutex_;
99 ffrt::mutex AppfreezeManager::catchStackMutex_;
100 std::map<int, std::string> AppfreezeManager::catchStackMap_;
101 ffrt::mutex AppfreezeManager::freezeFilterMutex_;
102 ffrt::mutex AppfreezeManager::freezeInfoMutex_;
103 std::string AppfreezeManager::appfreezeInfoPath_;
104
AppfreezeManager()105 AppfreezeManager::AppfreezeManager()
106 {
107 name_ = "AppfreezeManager" + std::to_string(AbilityRuntime::TimeUtil::CurrentTimeMillis());
108 }
109
~AppfreezeManager()110 AppfreezeManager::~AppfreezeManager()
111 {
112 }
113
GetInstance()114 std::shared_ptr<AppfreezeManager> AppfreezeManager::GetInstance()
115 {
116 if (instance_ == nullptr) {
117 std::lock_guard<ffrt::mutex> lock(singletonMutex_);
118 if (instance_ == nullptr) {
119 instance_ = std::make_shared<AppfreezeManager>();
120 }
121 }
122 return instance_;
123 }
124
DestroyInstance()125 void AppfreezeManager::DestroyInstance()
126 {
127 std::lock_guard<ffrt::mutex> lock(singletonMutex_);
128 if (instance_ != nullptr) {
129 instance_.reset();
130 instance_ = nullptr;
131 }
132 }
133
IsHandleAppfreeze(const std::string & bundleName)134 bool AppfreezeManager::IsHandleAppfreeze(const std::string& bundleName)
135 {
136 if (bundleName.empty()) {
137 return true;
138 }
139 return !DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->IsAttachDebug(bundleName);
140 }
141
AppfreezeHandle(const FaultData & faultData,const AppfreezeManager::AppInfo & appInfo)142 int AppfreezeManager::AppfreezeHandle(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo)
143 {
144 TAG_LOGD(AAFwkTag::APPDFR, "called %{public}s, bundleName %{public}s, name_ %{public}s",
145 faultData.errorObject.name.c_str(), appInfo.bundleName.c_str(), name_.c_str());
146 if (!IsHandleAppfreeze(appInfo.bundleName)) {
147 return -1;
148 }
149 HITRACE_METER_FMT(HITRACE_TAG_APP, "AppfreezeHandler:%{public}s bundleName:%{public}s",
150 faultData.errorObject.name.c_str(), appInfo.bundleName.c_str());
151 std::string memoryContent = "";
152 CollectFreezeSysMemory(memoryContent);
153 if (faultData.errorObject.name == AppFreezeType::APP_INPUT_BLOCK ||
154 faultData.errorObject.name == AppFreezeType::THREAD_BLOCK_3S ||
155 faultData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT ||
156 faultData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT_WARNING) {
157 AcquireStack(faultData, appInfo, memoryContent);
158 } else {
159 NotifyANR(faultData, appInfo, "", memoryContent);
160 }
161 return 0;
162 }
163
CollectFreezeSysMemory(std::string & memoryContent)164 void AppfreezeManager::CollectFreezeSysMemory(std::string& memoryContent)
165 {
166 memoryContent = "\nGet freeze memory start time: " + AbilityRuntime::TimeUtil::DefaultCurrentTimeStr() + "\n";
167 std::string tmp = "";
168 std::string pressMemInfo = "/proc/pressure/memory";
169 OHOS::LoadStringFromFile(pressMemInfo, tmp);
170 memoryContent += tmp + "\n";
171 std::string memInfoPath = "/proc/memview";
172 if (!OHOS::FileExists(memInfoPath)) {
173 memInfoPath = "/proc/meminfo";
174 }
175 OHOS::LoadStringFromFile(memInfoPath, tmp);
176 memoryContent += tmp + "\nGet freeze memory end time: " + AbilityRuntime::TimeUtil::DefaultCurrentTimeStr();
177 }
178
MergeNotifyInfo(FaultData & faultNotifyData,const AppfreezeManager::AppInfo & appInfo)179 int AppfreezeManager::MergeNotifyInfo(FaultData& faultNotifyData, const AppfreezeManager::AppInfo& appInfo)
180 {
181 std::string memoryContent;
182 CollectFreezeSysMemory(memoryContent);
183 std::string fileName = faultNotifyData.errorObject.name + "_" +
184 AbilityRuntime::TimeUtil::FormatTime("%Y%m%d%H%M%S") + "_" + std::to_string(appInfo.pid) + "_stack";
185 std::string catcherStack;
186 faultNotifyData.errorObject.message += "\nCatche stack trace start time: " +
187 AbilityRuntime::TimeUtil::DefaultCurrentTimeStr() + "\n";
188 if (faultNotifyData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT ||
189 faultNotifyData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT_WARNING) {
190 catcherStack += CatcherStacktrace(appInfo.pid, faultNotifyData.errorObject.stack);
191 } else {
192 catcherStack += CatchJsonStacktrace(appInfo.pid, faultNotifyData.errorObject.name,
193 faultNotifyData.errorObject.stack);
194 }
195 std::string timeStamp = "Catche stack trace end time: " + AbilityRuntime::TimeUtil::DefaultCurrentTimeStr();
196 faultNotifyData.errorObject.stack = WriteToFile(fileName, catcherStack);
197 if (appInfo.isOccurException) {
198 faultNotifyData.errorObject.message += "\nnotifyAppFault exception.\n";
199 }
200 faultNotifyData.errorObject.message += timeStamp;
201 if (faultNotifyData.errorObject.name == AppFreezeType::APP_INPUT_BLOCK ||
202 faultNotifyData.errorObject.name == AppFreezeType::THREAD_BLOCK_3S ||
203 faultNotifyData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT ||
204 faultNotifyData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT_WARNING) {
205 AcquireStack(faultNotifyData, appInfo, memoryContent);
206 } else {
207 NotifyANR(faultNotifyData, appInfo, "", memoryContent);
208 }
209 return 0;
210 }
211
AppfreezeHandleWithStack(const FaultData & faultData,const AppfreezeManager::AppInfo & appInfo)212 int AppfreezeManager::AppfreezeHandleWithStack(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo)
213 {
214 TAG_LOGW(AAFwkTag::APPDFR, "NotifyAppFaultTask called, eventName:%{public}s, bundleName:%{public}s, "
215 "name_:%{public}s, currentTime:%{public}s", faultData.errorObject.name.c_str(), appInfo.bundleName.c_str(),
216 name_.c_str(), AbilityRuntime::TimeUtil::DefaultCurrentTimeStr().c_str());
217 if (!IsHandleAppfreeze(appInfo.bundleName)) {
218 return -1;
219 }
220 FaultData faultNotifyData;
221 faultNotifyData.errorObject.name = faultData.errorObject.name;
222 faultNotifyData.errorObject.message = faultData.errorObject.message;
223 faultNotifyData.errorObject.stack = faultData.errorObject.stack;
224 faultNotifyData.faultType = FaultDataType::APP_FREEZE;
225 faultNotifyData.eventId = faultData.eventId;
226 faultNotifyData.tid = faultData.tid;
227 faultNotifyData.appfreezeInfo = faultData.appfreezeInfo;
228 faultNotifyData.appRunningUniqueId = faultData.appRunningUniqueId;
229 faultNotifyData.procStatm = faultData.procStatm;
230
231 HITRACE_METER_FMT(HITRACE_TAG_APP, "AppfreezeHandleWithStack pid:%{public}d-name:%{public}s",
232 appInfo.pid, faultData.errorObject.name.c_str());
233 return MergeNotifyInfo(faultNotifyData, appInfo);
234 }
235
WriteToFile(const std::string & fileName,std::string & content)236 std::string AppfreezeManager::WriteToFile(const std::string& fileName, std::string& content)
237 {
238 std::string dir_path = LOG_FILE_PATH + "/freeze";
239 constexpr mode_t defaultLogDirMode = 0770;
240 if (!OHOS::FileExists(dir_path)) {
241 OHOS::ForceCreateDirectory(dir_path);
242 OHOS::ChangeModeDirectory(dir_path, defaultLogDirMode);
243 }
244 std::string realPath;
245 if (!OHOS::PathToRealPath(dir_path, realPath)) {
246 TAG_LOGE(AAFwkTag::APPDFR, "pathToRealPath failed:%{public}s", dir_path.c_str());
247 return "";
248 }
249 std::string stackPath = realPath + "/" + fileName;
250 constexpr mode_t defaultLogFileMode = 0644;
251 FILE* fp = fopen(stackPath.c_str(), "w+");
252 chmod(stackPath.c_str(), defaultLogFileMode);
253 if (fp == nullptr) {
254 TAG_LOGI(AAFwkTag::APPDFR, "stackPath create failed, errno: %{public}d", errno);
255 return "";
256 } else {
257 TAG_LOGI(AAFwkTag::APPDFR, "stackPath: %{public}s", stackPath.c_str());
258 }
259 OHOS::SaveStringToFile(stackPath, content, true);
260 (void)fclose(fp);
261 return stackPath;
262 }
263
LifecycleTimeoutHandle(const ParamInfo & info,FreezeUtil::LifecycleFlow flow)264 int AppfreezeManager::LifecycleTimeoutHandle(const ParamInfo& info, FreezeUtil::LifecycleFlow flow)
265 {
266 if (info.typeId != AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT || !IsHandleAppfreeze(info.bundleName)) {
267 return -1;
268 }
269 if (info.eventName != AppFreezeType::LIFECYCLE_TIMEOUT && info.eventName != AppFreezeType::LIFECYCLE_HALF_TIMEOUT
270 && info.eventName != AppFreezeType::LIFECYCLE_TIMEOUT_WARNING
271 && info.eventName != AppFreezeType::LIFECYCLE_HALF_TIMEOUT_WARNING) {
272 return -1;
273 }
274 if (!g_betaVersion && info.eventName == AppFreezeType::LIFECYCLE_HALF_TIMEOUT) {
275 int32_t ret = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::AAFWK, "HIVIEW_HALF_FREEZE_LOG",
276 HiviewDFX::HiSysEvent::EventType::FAULT, "PID", info.pid, "PACKAGE_NAME", info.bundleName);
277 TAG_LOGW(AAFwkTag::APPDFR, "hisysevent write HIVIEW_HALF_FREEZE_LOG, pid:%{public}d, packageName:%{public}s,"
278 " ret:%{public}d", info.pid, info.bundleName.c_str(), ret);
279 }
280
281 TAG_LOGD(AAFwkTag::APPDFR, "called %{public}s, name_ %{public}s", info.bundleName.c_str(), name_.c_str());
282 HITRACE_METER_FMT(HITRACE_TAG_APP, "LifecycleTimeoutHandle:%{public}s bundleName:%{public}s",
283 info.eventName.c_str(), info.bundleName.c_str());
284
285 AppFaultDataBySA faultDataSA;
286 if (info.eventName == AppFreezeType::LIFECYCLE_TIMEOUT) {
287 std::ifstream statmStream("/proc/" + std::to_string(info.pid) + "/statm");
288 if (statmStream) {
289 std::string procStatm;
290 std::getline(statmStream, procStatm);
291 statmStream.close();
292 faultDataSA.procStatm = procStatm;
293 }
294 }
295 faultDataSA.errorObject.name = info.eventName;
296 faultDataSA.errorObject.message = info.msg;
297 faultDataSA.errorObject.stack = "\nDump tid stack start time:" +
298 AbilityRuntime::TimeUtil::DefaultCurrentTimeStr() + "\n";
299 std::string stack;
300 if (!HiviewDFX::GetBacktraceStringByTidWithMix(stack, info.pid, 0, true)) {
301 stack = "Failed to dump stacktrace for " + stack;
302 }
303 faultDataSA.errorObject.stack += stack + "\nDump tid stack end time:" +
304 AbilityRuntime::TimeUtil::DefaultCurrentTimeStr() + "\n";
305 faultDataSA.faultType = FaultDataType::APP_FREEZE;
306 faultDataSA.timeoutMarkers = "notifyFault" + std::to_string(info.pid) +
307 "-" + std::to_string(AbilityRuntime::TimeUtil::CurrentTimeMillis());
308 faultDataSA.pid = info.pid;
309 faultDataSA.needKillProcess = info.needKillProcess;
310 if (flow.state != AbilityRuntime::FreezeUtil::TimeoutState::UNKNOWN) {
311 faultDataSA.token = flow.token;
312 faultDataSA.state = static_cast<uint32_t>(flow.state);
313 }
314 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->NotifyAppFaultBySA(faultDataSA);
315 return 0;
316 }
317
GetFaultNotifyData(const FaultData & faultData,int pid)318 FaultData AppfreezeManager::GetFaultNotifyData(const FaultData& faultData, int pid)
319 {
320 FaultData faultNotifyData;
321 faultNotifyData.errorObject.name = faultData.errorObject.name;
322 faultNotifyData.errorObject.message = faultData.errorObject.message;
323 faultNotifyData.errorObject.stack = faultData.errorObject.stack;
324 faultNotifyData.faultType = FaultDataType::APP_FREEZE;
325 faultNotifyData.eventId = faultData.eventId;
326 faultNotifyData.tid = (faultData.errorObject.name == AppFreezeType::APP_INPUT_BLOCK) ? pid : faultData.tid;
327 faultNotifyData.appfreezeInfo = faultData.appfreezeInfo;
328 faultNotifyData.appRunningUniqueId = faultData.appRunningUniqueId;
329 faultNotifyData.procStatm = faultData.procStatm;
330 return faultNotifyData;
331 }
332
AcquireStack(const FaultData & faultData,const AppfreezeManager::AppInfo & appInfo,const std::string & memoryContent)333 int AppfreezeManager::AcquireStack(const FaultData& faultData,
334 const AppfreezeManager::AppInfo& appInfo, const std::string& memoryContent)
335 {
336 int pid = appInfo.pid;
337 FaultData faultNotifyData = GetFaultNotifyData(faultData, pid);
338
339 std::string binderInfo;
340 std::string binderPidsStr;
341 std::string terminalBinderTid;
342 AppfreezeManager::TerminalBinder terminalBinder = {0, 0};
343 AppfreezeManager::ParseBinderParam params = {pid, faultNotifyData.tid, pid, 0};
344 std::set<int> asyncPids;
345 std::set<int> syncPids = GetBinderPeerPids(binderInfo, params, asyncPids, terminalBinder);
346 if (syncPids.empty()) {
347 binderInfo +="PeerBinder pids is empty\n";
348 }
349 for (auto& pidTemp : syncPids) {
350 TAG_LOGI(AAFwkTag::APPDFR, "PeerBinder pidTemp pids:%{public}d", pidTemp);
351 if (pidTemp == pid) {
352 continue;
353 }
354 std::string content = "Binder catcher stacktrace, type is peer, pid : " + std::to_string(pidTemp) + "\n";
355 content += CatcherStacktrace(pidTemp, "");
356 binderPidsStr += " " + std::to_string(pidTemp);
357 if (terminalBinder.pid > 0 && pidTemp == terminalBinder.pid) {
358 terminalBinder.tid = (terminalBinder.tid > 0) ? terminalBinder.tid : terminalBinder.pid;
359 content = "Binder catcher stacktrace, terminal binder tag\n" + content +
360 "Binder catcher stacktrace, terminal binder tag\n";
361 terminalBinderTid = std::to_string(terminalBinder.tid);
362 }
363 binderInfo += content;
364 }
365 for (auto& pidTemp : asyncPids) {
366 TAG_LOGI(AAFwkTag::APPDFR, "AsyncBinder pidTemp pids:%{public}d", pidTemp);
367 if (pidTemp != pid && syncPids.find(pidTemp) == syncPids.end()) {
368 std::string content = "Binder catcher stacktrace, type is async, pid : " + std::to_string(pidTemp) + "\n";
369 content += CatcherStacktrace(pidTemp, "");
370 binderInfo += content;
371 }
372 }
373
374 std::string fileName = faultData.errorObject.name + "_" +
375 AbilityRuntime::TimeUtil::FormatTime("%Y%m%d%H%M%S") + "_" + std::to_string(pid) + "_binder";
376 std::string fullStackPath = WriteToFile(fileName, binderInfo);
377 binderInfo = fullStackPath + "," + binderPidsStr + "," + terminalBinderTid;
378
379 int ret = NotifyANR(faultNotifyData, appInfo, binderInfo, memoryContent);
380 return ret;
381 }
382
ParseDecToHex(uint64_t id)383 std::string AppfreezeManager::ParseDecToHex(uint64_t id)
384 {
385 std::stringstream ss;
386 ss << std::hex << std::setfill('0') << std::setw(CHARACTER_WIDTH) << id;
387 return ss.str();
388 }
389
GetHitraceId(HitraceInfo & info)390 bool AppfreezeManager::GetHitraceId(HitraceInfo& info)
391 {
392 #ifdef ABILITY_RUNTIME_HITRACE_ENABLE
393 OHOS::HiviewDFX::HiTraceId hitraceId = OHOS::HiviewDFX::HiTraceChain::GetId();
394 if (hitraceId.IsValid() == 0) {
395 TAG_LOGW(AAFwkTag::APPDFR, "get hitrace id is invalid.");
396 return false;
397 }
398 info.hiTraceChainId = ParseDecToHex(hitraceId.GetChainId());
399 info.spanId = ParseDecToHex(hitraceId.GetSpanId());
400 info.pspanId = ParseDecToHex(hitraceId.GetParentSpanId());
401 info.traceFlag = ParseDecToHex(hitraceId.GetFlags());
402 TAG_LOGW(AAFwkTag::APPDFR,
403 "hiTraceChainId:%{public}s, spanId:%{public}s, pspanId:%{public}s, traceFlag:%{public}s",
404 info.hiTraceChainId.c_str(), info.spanId.c_str(), info.pspanId.c_str(), info.traceFlag.c_str());
405 return true;
406 #endif
407 return false;
408 }
409
ReportAppfreezeCpuInfo(const FaultData & faultData,const AppfreezeManager::AppInfo & appInfo)410 std::string AppfreezeManager::ReportAppfreezeCpuInfo(const FaultData& faultData,
411 const AppfreezeManager::AppInfo& appInfo)
412 {
413 std::string filePath;
414 if (faultData.errorObject.name == AppFreezeType::THREAD_BLOCK_3S) {
415 AppExecFwk::AppfreezeCpuFreqManager::GetInstance().InitCpuDataProcessor(
416 EVENT_APPFREEZE_TYPE, appInfo.pid, appInfo.uid, faultData.appfreezeInfo);
417 } else if (faultData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT) {
418 AppExecFwk::AppfreezeCpuFreqManager::GetInstance().InitCpuDataProcessor(
419 EVENT_SYSFREEZE_TYPE, appInfo.pid, appInfo.uid, faultData.appfreezeInfo);
420 } else if (faultData.errorObject.name == AppFreezeType::THREAD_BLOCK_6S) {
421 filePath = AppExecFwk::AppfreezeCpuFreqManager::GetInstance().WriteCpuInfoToFile(
422 EVENT_APPFREEZE_TYPE, appInfo.bundleName, appInfo.uid, appInfo.pid, faultData.errorObject.name);
423 } else if (faultData.errorObject.name == AppFreezeType::LIFECYCLE_TIMEOUT) {
424 filePath = AppExecFwk::AppfreezeCpuFreqManager::GetInstance().WriteCpuInfoToFile(
425 EVENT_SYSFREEZE_TYPE, appInfo.bundleName, appInfo.uid, appInfo.pid, faultData.errorObject.name);
426 }
427 TAG_LOGI(AAFwkTag::APPDFR, "report appfreeze name:%{public}s, appfreezeInfo:%{public}s, path:%{public}s",
428 faultData.errorObject.name.c_str(), faultData.appfreezeInfo.c_str(), filePath.c_str());
429 return filePath;
430 }
431
NotifyANR(const FaultData & faultData,const AppfreezeManager::AppInfo & appInfo,const std::string & binderInfo,const std::string & memoryContent)432 int AppfreezeManager::NotifyANR(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo,
433 const std::string& binderInfo, const std::string& memoryContent)
434 {
435 std::string appRunningUniqueId = faultData.appRunningUniqueId;
436 int ret = 0;
437 this->PerfStart(faultData.errorObject.name);
438 int64_t startTime = AbilityRuntime::TimeUtil::CurrentTimeMillis();
439 if (faultData.errorObject.name == AppFreezeType::APP_INPUT_BLOCK) {
440 ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, faultData.errorObject.name,
441 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_UID, appInfo.uid, EVENT_PID, appInfo.pid,
442 EVENT_PACKAGE_NAME, appInfo.bundleName, EVENT_PROCESS_NAME, appInfo.processName, EVENT_MESSAGE,
443 faultData.errorObject.message, EVENT_STACK, faultData.errorObject.stack, BINDER_INFO, binderInfo,
444 APP_RUNNING_UNIQUE_ID, appRunningUniqueId, EVENT_INPUT_ID, faultData.eventId,
445 FREEZE_MEMORY, memoryContent + "\n" + faultData.procStatm);
446 } else if (faultData.errorObject.name == AppFreezeType::THREAD_BLOCK_6S) {
447 HitraceInfo info;
448 bool hitraceIsValid = GetHitraceId(info);
449 ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, faultData.errorObject.name,
450 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_UID, appInfo.uid, EVENT_PID, appInfo.pid,
451 EVENT_TID, faultData.tid,
452 EVENT_PACKAGE_NAME, appInfo.bundleName, EVENT_PROCESS_NAME, appInfo.processName, EVENT_MESSAGE,
453 faultData.errorObject.message, EVENT_STACK, faultData.errorObject.stack, BINDER_INFO, binderInfo,
454 APP_RUNNING_UNIQUE_ID, appRunningUniqueId, FREEZE_MEMORY, memoryContent + "\n" + faultData.procStatm,
455 EVENT_TRACE_ID, hitraceIsValid ? info.hiTraceChainId : "",
456 EVENT_SPAN_ID, hitraceIsValid ? info.spanId : "",
457 EVENT_PARENT_SPAN_ID, hitraceIsValid ? info.pspanId : "",
458 EVENT_TRACE_FLAG, hitraceIsValid ? info.traceFlag : "",
459 FREEZE_INFO_PATH, ReportAppfreezeCpuInfo(faultData, appInfo));
460 } else {
461 ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, faultData.errorObject.name,
462 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_UID, appInfo.uid, EVENT_PID, appInfo.pid,
463 EVENT_TID, faultData.tid > 0 ? faultData.tid : appInfo.pid,
464 EVENT_PACKAGE_NAME, appInfo.bundleName, EVENT_PROCESS_NAME, appInfo.processName, EVENT_MESSAGE,
465 faultData.errorObject.message, EVENT_STACK, faultData.errorObject.stack, BINDER_INFO, binderInfo,
466 APP_RUNNING_UNIQUE_ID, appRunningUniqueId, FREEZE_MEMORY, memoryContent + "\n" + faultData.procStatm,
467 FREEZE_INFO_PATH, ReportAppfreezeCpuInfo(faultData, appInfo));
468 }
469 TAG_LOGW(AAFwkTag::APPDFR,
470 "reportEvent:%{public}s, pid:%{public}d, tid:%{public}d, bundleName:%{public}s, appRunningUniqueId:%{public}s"
471 ", endTime:%{public}s, interval:%{public}" PRId64 " ms, eventId:%{public}d hisysevent write ret: %{public}d",
472 faultData.errorObject.name.c_str(), appInfo.pid, faultData.tid, appInfo.bundleName.c_str(),
473 appRunningUniqueId.c_str(), AbilityRuntime::TimeUtil::DefaultCurrentTimeStr().c_str(),
474 AbilityRuntime::TimeUtil::CurrentTimeMillis() - startTime, faultData.eventId, ret);
475 #ifdef ABILITY_RUNTIME_HITRACE_ENABLE
476 OHOS::HiviewDFX::HiTraceChain::ClearId();
477 #endif
478 return 0;
479 }
480
BinderParser(std::ifstream & fin,std::string & stack,std::set<int> & asyncPids) const481 std::map<int, std::list<AppfreezeManager::PeerBinderInfo>> AppfreezeManager::BinderParser(std::ifstream& fin,
482 std::string& stack, std::set<int>& asyncPids) const
483 {
484 std::map<uint32_t, uint32_t> asyncBinderMap;
485 std::vector<std::pair<uint32_t, uint64_t>> freeAsyncSpacePairs;
486 std::map<int, std::list<AppfreezeManager::PeerBinderInfo>> binderInfos = BinderLineParser(fin, stack,
487 asyncBinderMap, freeAsyncSpacePairs);
488
489 if (!g_overseaVersion) {
490 std::sort(freeAsyncSpacePairs.begin(), freeAsyncSpacePairs.end(),
491 [] (const auto& pairOne, const auto& pairTwo) { return pairOne.second < pairTwo.second; });
492 std::vector<std::pair<uint32_t, uint32_t>> asyncBinderPairs(asyncBinderMap.begin(), asyncBinderMap.end());
493 std::sort(asyncBinderPairs.begin(), asyncBinderPairs.end(),
494 [] (const auto& pairOne, const auto& pairTwo) { return pairOne.second > pairTwo.second; });
495
496 size_t freeAsyncSpaceSize = freeAsyncSpacePairs.size();
497 size_t asyncBinderSize = asyncBinderPairs.size();
498 size_t individualMaxSize = 2;
499 for (size_t i = 0; i < individualMaxSize; i++) {
500 if (i < freeAsyncSpaceSize) {
501 asyncPids.insert(freeAsyncSpacePairs[i].first);
502 }
503 if (i < asyncBinderSize) {
504 asyncPids.insert(asyncBinderPairs[i].first);
505 }
506 }
507 }
508 return binderInfos;
509 }
510
BinderLineParser(std::ifstream & fin,std::string & stack,std::map<uint32_t,uint32_t> & asyncBinderMap,std::vector<std::pair<uint32_t,uint64_t>> & freeAsyncSpacePairs) const511 std::map<int, std::list<AppfreezeManager::PeerBinderInfo>> AppfreezeManager::BinderLineParser(std::ifstream& fin,
512 std::string& stack, std::map<uint32_t, uint32_t>& asyncBinderMap,
513 std::vector<std::pair<uint32_t, uint64_t>>& freeAsyncSpacePairs) const
514 {
515 std::map<int, std::list<AppfreezeManager::PeerBinderInfo>> binderInfos;
516 std::string line;
517 bool isBinderMatchup = false;
518 TAG_LOGI(AAFwkTag::APPDFR, "start");
519 stack += "BinderCatcher --\n\n";
520 while (getline(fin, line)) {
521 stack += line + "\n";
522 isBinderMatchup = (!isBinderMatchup && line.find("free_async_space") != line.npos) ? true : isBinderMatchup;
523 std::vector<std::string> strList = GetFileToList(line);
524
525 if (isBinderMatchup) {
526 if (g_overseaVersion) {
527 break;
528 } else if (line.find("free_async_space") == line.npos && strList.size() == ARR_SIZE &&
529 std::atoll(strList[FREE_ASYNC_INDEX].c_str()) < FREE_ASYNC_MAX) {
530 freeAsyncSpacePairs.emplace_back(std::atoi(strList[0].c_str()),
531 std::atoll(strList[FREE_ASYNC_INDEX].c_str()));
532 }
533 } else if (line.find("async\t") != std::string::npos && strList.size() > ARR_SIZE) {
534 if (g_overseaVersion) {
535 continue;
536 }
537 std::string serverPid = StrSplit(strList[3], 0);
538 std::string serverTid = StrSplit(strList[3], 1);
539 if (serverPid != "" && serverTid != "" && std::atoi(serverTid.c_str()) == 0) {
540 asyncBinderMap[std::atoi(serverPid.c_str())]++;
541 }
542 } else if (strList.size() >= ARR_SIZE) { // 7: valid array size
543 AppfreezeManager::PeerBinderInfo info = {0};
544 // 0: local id,
545 std::string clientPid = StrSplit(strList[0], 0);
546 std::string clientTid = StrSplit(strList[0], 1);
547 // 2: peer id,
548 std::string serverPid = StrSplit(strList[2], 0);
549 std::string serverTid = StrSplit(strList[2], 1);
550 // 5: wait time, s
551 std::string wait = StrSplit(strList[5], 1);
552 if (clientPid == "" || clientTid == "" || serverPid == "" || serverTid == "" || wait == "") {
553 continue;
554 }
555 info = {std::strtol(clientPid.c_str(), nullptr, DECIMAL), std::strtol(clientTid.c_str(), nullptr, DECIMAL),
556 std::strtol(serverPid.c_str(), nullptr, DECIMAL), strtol(serverTid.c_str(), nullptr, DECIMAL)};
557 int waitTime = std::strtol(wait.c_str(), nullptr, DECIMAL);
558 TAG_LOGI(AAFwkTag::APPDFR, "server:%{public}d, client:%{public}d, wait:%{public}d", info.serverPid,
559 info.clientPid, waitTime);
560 binderInfos[info.clientPid].push_back(info);
561 }
562 }
563 TAG_LOGI(AAFwkTag::APPDFR, "binderInfos size: %{public}zu", binderInfos.size());
564 return binderInfos;
565 }
566
GetFileToList(std::string line) const567 std::vector<std::string> AppfreezeManager::GetFileToList(std::string line) const
568 {
569 std::vector<std::string> strList;
570 std::istringstream lineStream(line);
571 std::string tmpstr;
572 while (lineStream >> tmpstr) {
573 strList.push_back(tmpstr);
574 }
575 TAG_LOGD(AAFwkTag::APPDFR, "strList size: %{public}zu", strList.size());
576 return strList;
577 }
578
StrSplit(const std::string & str,uint16_t index) const579 std::string AppfreezeManager::StrSplit(const std::string& str, uint16_t index) const
580 {
581 std::vector<std::string> strings;
582 SplitStr(str, ":", strings);
583 return index < strings.size() ? strings[index] : "";
584 }
585
GetBinderPeerPids(std::string & stack,AppfreezeManager::ParseBinderParam params,std::set<int> & asyncPids,AppfreezeManager::TerminalBinder & terminalBinder) const586 std::set<int> AppfreezeManager::GetBinderPeerPids(std::string& stack, AppfreezeManager::ParseBinderParam params,
587 std::set<int>& asyncPids, AppfreezeManager::TerminalBinder& terminalBinder) const
588 {
589 std::set<int> pids;
590 std::ifstream fin;
591 std::string path = LOGGER_DEBUG_PROC_PATH;
592 char resolvePath[PATH_MAX] = {0};
593 if (realpath(path.c_str(), resolvePath) == nullptr) {
594 TAG_LOGE(AAFwkTag::APPDFR, "invalid realpath");
595 return pids;
596 }
597 fin.open(resolvePath);
598 if (!fin.is_open()) {
599 TAG_LOGE(AAFwkTag::APPDFR, "open failed, %{public}s", resolvePath);
600 stack += "open file failed :" + path + "\r\n";
601 return pids;
602 }
603
604 stack += "\n\nPeerBinderCatcher -- pid==" + std::to_string(params.pid) + "\n\n";
605 std::map<int, std::list<AppfreezeManager::PeerBinderInfo>> binderInfos = BinderParser(fin, stack, asyncPids);
606 fin.close();
607
608 if (binderInfos.size() == 0 || binderInfos.find(params.pid) == binderInfos.end()) {
609 return pids;
610 }
611
612 ParseBinderPids(binderInfos, pids, params, true, terminalBinder);
613 for (auto& each : pids) {
614 TAG_LOGD(AAFwkTag::APPDFR, "each pids:%{public}d", each);
615 }
616 return pids;
617 }
618
ParseBinderPids(const std::map<int,std::list<AppfreezeManager::PeerBinderInfo>> & binderInfos,std::set<int> & pids,AppfreezeManager::ParseBinderParam params,bool getTerminal,AppfreezeManager::TerminalBinder & terminalBinder) const619 void AppfreezeManager::ParseBinderPids(const std::map<int, std::list<AppfreezeManager::PeerBinderInfo>>& binderInfos,
620 std::set<int>& pids, AppfreezeManager::ParseBinderParam params, bool getTerminal,
621 AppfreezeManager::TerminalBinder& terminalBinder) const
622 {
623 auto it = binderInfos.find(params.pid);
624 params.layer++;
625 if (params.layer >= MAX_LAYER || it == binderInfos.end()) {
626 return;
627 }
628
629 for (auto& each : it->second) {
630 pids.insert(each.serverPid);
631 params.pid = each.serverPid;
632 if (getTerminal && ((each.clientPid == params.eventPid && each.clientTid == params.eventTid) ||
633 (each.clientPid == terminalBinder.pid && each.clientTid == terminalBinder.tid))) {
634 terminalBinder.pid = each.serverPid;
635 terminalBinder.tid = each.serverTid;
636 ParseBinderPids(binderInfos, pids, params, true, terminalBinder);
637 } else {
638 ParseBinderPids(binderInfos, pids, params, false, terminalBinder);
639 }
640 }
641 }
642
DeleteStack(int pid)643 void AppfreezeManager::DeleteStack(int pid)
644 {
645 std::lock_guard<ffrt::mutex> lock(catchStackMutex_);
646 auto it = catchStackMap_.find(pid);
647 if (it != catchStackMap_.end()) {
648 catchStackMap_.erase(it);
649 }
650 }
651
FindStackByPid(std::string & msg,int pid) const652 void AppfreezeManager::FindStackByPid(std::string& msg, int pid) const
653 {
654 std::lock_guard<ffrt::mutex> lock(catchStackMutex_);
655 auto it = catchStackMap_.find(pid);
656 if (it != catchStackMap_.end()) {
657 msg = it->second;
658 }
659 }
660
CatchJsonStacktrace(int pid,const std::string & faultType,const std::string & stack) const661 std::string AppfreezeManager::CatchJsonStacktrace(int pid, const std::string& faultType,
662 const std::string& stack) const
663 {
664 HITRACE_METER_FMT(HITRACE_TAG_APP, "CatchJsonStacktrace pid:%{public}d", pid);
665 HiviewDFX::DfxDumpCatcher dumplog;
666 std::string msg;
667 int timeout = 3000;
668 int tid = 0;
669 std::pair<int, std::string> dumpResult = dumplog.DumpCatchWithTimeout(pid, msg, timeout, tid, true);
670 if (dumpResult.first == DUMP_STACK_FAILED) {
671 TAG_LOGI(AAFwkTag::APPDFR, "appfreeze catch json stacktrace failed, %{public}s", dumpResult.second.c_str());
672 msg = "Failed to dump stacktrace for " + std::to_string(pid) + "\n" + dumpResult.second + "\n" + msg +
673 "\nMain thread stack:" + stack;
674 if (faultType == AppFreezeType::APP_INPUT_BLOCK) {
675 FindStackByPid(msg, pid);
676 }
677 } else {
678 if (dumpResult.first == DUMP_KERNEL_STACK_SUCCESS) {
679 msg = "Failed to dump normal stacktrace for " + std::to_string(pid) + "\n" + dumpResult.second +
680 "Kernel stack is:\n" + msg;
681 }
682 if (faultType == AppFreezeType::THREAD_BLOCK_3S) {
683 std::lock_guard<ffrt::mutex> lock(catchStackMutex_);
684 catchStackMap_[pid] = msg;
685 }
686 }
687 return msg;
688 }
689
CatcherStacktrace(int pid,const std::string & stack) const690 std::string AppfreezeManager::CatcherStacktrace(int pid, const std::string& stack) const
691 {
692 HITRACE_METER_FMT(HITRACE_TAG_APP, "CatcherStacktrace pid:%{public}d", pid);
693 HiviewDFX::DfxDumpCatcher dumplog;
694 std::string msg;
695 std::pair<int, std::string> dumpResult = dumplog.DumpCatchWithTimeout(pid, msg);
696 if (dumpResult.first == DUMP_STACK_FAILED) {
697 TAG_LOGI(AAFwkTag::APPDFR, "appfreeze catch stacktrace failed, %{public}s",
698 dumpResult.second.c_str());
699 msg = "Failed to dump stacktrace for " + std::to_string(pid) + "\n" + dumpResult.second + "\n" + msg +
700 "\nMain thread stack:" + stack;
701 } else if (dumpResult.first == DUMP_KERNEL_STACK_SUCCESS) {
702 msg = "Failed to dump normal stacktrace for " + std::to_string(pid) + "\n" + dumpResult.second +
703 "Kernel stack is:\n" + msg;
704 }
705 return msg;
706 }
707
IsProcessDebug(int32_t pid,std::string bundleName)708 bool AppfreezeManager::IsProcessDebug(int32_t pid, std::string bundleName)
709 {
710 std::lock_guard<ffrt::mutex> lock(freezeFilterMutex_);
711 auto it = appfreezeFilterMap_.find(bundleName);
712 if (it != appfreezeFilterMap_.end() && it->second.pid == pid) {
713 bool result = it->second.state == AppFreezeState::APPFREEZE_STATE_CANCELED;
714 TAG_LOGW(AAFwkTag::APPDFR, "AppfreezeFilter: %{public}d, "
715 "bundleName=%{public}s, pid:%{public}d, state:%{public}d, g_betaVersion:%{public}d,"
716 " g_developMode:%{public}d",
717 result, bundleName.c_str(), pid, it->second.state, g_betaVersion, g_developMode);
718 return result;
719 }
720
721 const int buffSize = 128;
722 char paramBundle[buffSize] = {0};
723 GetParameter("hiviewdfx.appfreeze.filter_bundle_name", "", paramBundle, buffSize - 1);
724 std::string debugBundle(paramBundle);
725
726 if (bundleName.compare(debugBundle) == 0) {
727 TAG_LOGI(AAFwkTag::APPDFR, "filtration %{public}s_%{public}s not exit",
728 debugBundle.c_str(), bundleName.c_str());
729 return true;
730 }
731 return false;
732 }
733
GetFreezeCurrentTime()734 int64_t AppfreezeManager::GetFreezeCurrentTime()
735 {
736 struct timespec t;
737 t.tv_sec = 0;
738 t.tv_nsec = 0;
739 clock_gettime(CLOCK_MONOTONIC, &t);
740 return static_cast<int64_t>(((t.tv_sec) * NANOSECONDS + t.tv_nsec) / MICROSECONDS);
741 }
742
SetFreezeState(int32_t pid,int state,const std::string & errorName)743 void AppfreezeManager::SetFreezeState(int32_t pid, int state, const std::string& errorName)
744 {
745 std::lock_guard<ffrt::mutex> lock(freezeMutex_);
746 if (appfreezeInfo_.find(pid) != appfreezeInfo_.end()) {
747 appfreezeInfo_[pid].state = state;
748 appfreezeInfo_[pid].occurTime = GetFreezeCurrentTime();
749 } else {
750 AppFreezeInfo info;
751 info.pid = pid;
752 info.state = state;
753 info.occurTime = GetFreezeCurrentTime();
754 info.errorName = errorName;
755 appfreezeInfo_.emplace(pid, info);
756 }
757 }
758
GetFreezeState(int32_t pid)759 int AppfreezeManager::GetFreezeState(int32_t pid)
760 {
761 std::lock_guard<ffrt::mutex> lock(freezeMutex_);
762 auto it = appfreezeInfo_.find(pid);
763 if (it != appfreezeInfo_.end()) {
764 return it->second.state;
765 }
766 return AppFreezeState::APPFREEZE_STATE_IDLE;
767 }
768
GetFreezeTime(int32_t pid)769 int64_t AppfreezeManager::GetFreezeTime(int32_t pid)
770 {
771 std::lock_guard<ffrt::mutex> lock(freezeMutex_);
772 auto it = appfreezeInfo_.find(pid);
773 if (it != appfreezeInfo_.end()) {
774 return it->second.occurTime;
775 }
776 return 0;
777 }
778
ClearOldInfo()779 void AppfreezeManager::ClearOldInfo()
780 {
781 std::lock_guard<ffrt::mutex> lock(freezeMutex_);
782 int64_t currentTime = GetFreezeCurrentTime();
783 for (auto it = appfreezeInfo_.begin(); it != appfreezeInfo_.end();) {
784 auto diff = currentTime - it->second.occurTime;
785 if (diff > FREEZE_TIME_LIMIT) {
786 it = appfreezeInfo_.erase(it);
787 } else {
788 ++it;
789 }
790 }
791 }
792
IsNeedIgnoreFreezeEvent(int32_t pid,const std::string & errorName)793 bool AppfreezeManager::IsNeedIgnoreFreezeEvent(int32_t pid, const std::string& errorName)
794 {
795 if (appfreezeInfo_.size() >= FREEZEMAP_SIZE_MAX) {
796 ClearOldInfo();
797 }
798 int state = GetFreezeState(pid);
799 int64_t currentTime = GetFreezeCurrentTime();
800 int64_t lastTime = GetFreezeTime(pid);
801 auto diff = currentTime - lastTime;
802 if (state == AppFreezeState::APPFREEZE_STATE_FREEZE) {
803 if (diff >= FREEZE_TIME_LIMIT) {
804 TAG_LOGI(AAFwkTag::APPDFR, "durationTime: "
805 "%{public}" PRId64 "state: %{public}d", diff, state);
806 return false;
807 }
808 return true;
809 } else {
810 if (errorName == "THREAD_BLOCK_3S") {
811 return false;
812 }
813 SetFreezeState(pid, AppFreezeState::APPFREEZE_STATE_FREEZE, errorName);
814 TAG_LOGI(AAFwkTag::APPDFR, "durationTime: %{public}" PRId64 ", SetFreezeState: "
815 "%{public}s", diff, errorName.c_str());
816 return false;
817 }
818 }
819
CancelAppFreezeDetect(int32_t pid,const std::string & bundleName)820 bool AppfreezeManager::CancelAppFreezeDetect(int32_t pid, const std::string& bundleName)
821 {
822 if (bundleName.empty()) {
823 TAG_LOGE(AAFwkTag::APPDFR, "SetAppFreezeFilter: failed, bundleName is empty.");
824 return false;
825 }
826 std::lock_guard<ffrt::mutex> lock(freezeFilterMutex_);
827 AppFreezeInfo info;
828 info.pid = pid;
829 info.state = AppFreezeState::APPFREEZE_STATE_CANCELING;
830 appfreezeFilterMap_.emplace(bundleName, info);
831 TAG_LOGI(AAFwkTag::APPDFR, "SetAppFreezeFilter: success, bundleName=%{public}s, "
832 "pid:%{public}d, state:%{public}d", bundleName.c_str(), info.pid, info.state);
833 return true;
834 }
835
RemoveDeathProcess(std::string bundleName)836 void AppfreezeManager::RemoveDeathProcess(std::string bundleName)
837 {
838 std::lock_guard<ffrt::mutex> lock(freezeFilterMutex_);
839 auto it = appfreezeFilterMap_.find(bundleName);
840 if (it != appfreezeFilterMap_.end()) {
841 TAG_LOGI(AAFwkTag::APPDFR, "RemoveAppFreezeFilter:success, bundleName: %{public}s",
842 bundleName.c_str());
843 appfreezeFilterMap_.erase(it);
844 } else {
845 TAG_LOGI(AAFwkTag::APPDFR, "RemoveAppFreezeFilter:failed, not found bundleName: "
846 "%{public}s", bundleName.c_str());
847 }
848 }
849
ResetAppfreezeState(int32_t pid,const std::string & bundleName)850 void AppfreezeManager::ResetAppfreezeState(int32_t pid, const std::string& bundleName)
851 {
852 std::lock_guard<ffrt::mutex> lock(freezeFilterMutex_);
853 if (appfreezeFilterMap_.find(bundleName) != appfreezeFilterMap_.end()) {
854 appfreezeFilterMap_[bundleName].state = AppFreezeState::APPFREEZE_STATE_CANCELED;
855 }
856 TAG_LOGI(AAFwkTag::APPDFR, "SetAppFreezeFilter: reset state, "
857 "bundleName=%{public}s, pid:%{public}d, state:%{public}d",
858 bundleName.c_str(), pid, appfreezeFilterMap_[bundleName].state);
859 }
860
IsValidFreezeFilter(int32_t pid,const std::string & bundleName)861 bool AppfreezeManager::IsValidFreezeFilter(int32_t pid, const std::string& bundleName)
862 {
863 if (g_betaVersion || g_developMode) {
864 TAG_LOGI(AAFwkTag::APPDFR, "SetAppFreezeFilter: "
865 "current device is beta or development");
866 return true;
867 }
868 std::lock_guard<ffrt::mutex> lock(freezeFilterMutex_);
869 bool ret = appfreezeFilterMap_.find(bundleName) != appfreezeFilterMap_.end();
870 TAG_LOGI(AAFwkTag::APPDFR, "SetAppFreezeFilter: %{public}d, bundleName=%{public}s, "
871 "pid:%{public}d", ret, bundleName.c_str(), pid);
872 return ret;
873 }
PerfStart(std::string eventName)874 void AppfreezeManager::PerfStart(std::string eventName)
875 {
876 if (OHOS::system::GetParameter("const.dfx.sub_health_recovery.enable", "") != "true") {
877 TAG_LOGI(AAFwkTag::APPDFR, "sub_health_recovery is not enable");
878 return;
879 }
880 auto it = HALF_EVENT_CONFIGS.find(eventName);
881 if (it == HALF_EVENT_CONFIGS.end()) {
882 return;
883 }
884 auto curTime = AbilityRuntime::TimeUtil::SystemTimeMillisecond();
885 if (curTime - perfTime < PERF_TIME) {
886 TAG_LOGE(AAFwkTag::APPDFR, "perf time is less than 60s");
887 return;
888 }
889 std::string bigCpuCurFreq = this->GetFirstLine(TWELVE_BIG_CPU_CUR_FREQ);
890 std::string bigCpuMaxFreq = this->GetFirstLine(TWELVE_BIG_CPU_MAX_FREQ);
891 std::string midCpuCurFreq = this->GetFirstLine(TWELVE_MID_CPU_CUR_FREQ);
892 std::string midCpuMaxFreq = this->GetFirstLine(TWELVE_MID_CPU_MAX_FREQ);
893 if (bigCpuCurFreq == bigCpuMaxFreq || midCpuCurFreq == midCpuMaxFreq) {
894 perfTime = curTime;
895 TAG_LOGI(AAFwkTag::APPDFR, "perf start");
896 AAFwk::ResSchedUtil::GetInstance().ReportSubHealtyPerfInfoToRSS();
897 TAG_LOGI(AAFwkTag::APPDFR, "perf end");
898 }
899 }
GetFirstLine(const std::string & path)900 std::string AppfreezeManager::GetFirstLine(const std::string &path)
901 {
902 std::string realPath;
903 if (!OHOS::PathToRealPath(path, realPath)) {
904 TAG_LOGE(AAFwkTag::APPDFR, "realpath failed, path:%{public}s errno:%{public}d",
905 path.c_str(), errno);
906 return "";
907 }
908 std::ifstream inFile(realPath.c_str());
909 if (!inFile) {
910 return "";
911 }
912 std::string firstLine;
913 getline(inFile, firstLine);
914 inFile.close();
915 return firstLine;
916 }
917 } // namespace AAFwk
918 } // namespace OHOS