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