mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-25 12:23:20 -04:00
update background detect
Signed-off-by: acdemicJava <yinhuiling@h-partners.com>
This commit is contained in:
@@ -121,7 +121,9 @@ void AppfreezeInner::GetMainHandlerDump(std::string& msgContent)
|
||||
void AppfreezeInner::ChangeFaultDateInfo(FaultData& faultData, const std::string& msgContent)
|
||||
{
|
||||
faultData.errorObject.message += msgContent;
|
||||
faultData.faultType = FaultDataType::APP_FREEZE;
|
||||
faultData.isInForeground = GetAppInForeground();
|
||||
bool isInBackGround = AppExecFwk::AppfreezeManager::GetInstance()->CheckInBackGround(faultData);
|
||||
faultData.faultType = isInBackGround ? FaultDataType::BACKGROUND_WARNING : FaultDataType::APP_FREEZE;
|
||||
faultData.notifyApp = false;
|
||||
faultData.waitSaveState = false;
|
||||
faultData.forceExit = false;
|
||||
@@ -138,7 +140,8 @@ void AppfreezeInner::ChangeFaultDateInfo(FaultData& faultData, const std::string
|
||||
if (isExit) {
|
||||
faultData.forceExit = true;
|
||||
faultData.waitSaveState = AppRecovery::GetInstance().IsEnabled();
|
||||
AAFwk::ExitReason exitReason = {REASON_APP_FREEZE, "Kill Reason:" + faultData.errorObject.name};
|
||||
std::string reason = isInBackGround ? "Background warning" : faultData.errorObject.name;
|
||||
AAFwk::ExitReason exitReason = {REASON_APP_FREEZE, "Kill Reason:" + reason};
|
||||
AbilityManagerClient::GetInstance()->RecordAppExitReason(exitReason);
|
||||
}
|
||||
NotifyANR(faultData);
|
||||
@@ -153,7 +156,6 @@ void AppfreezeInner::AppfreezeHandleOverReportCount(bool isSixSecondEvent)
|
||||
faultData.errorObject.message =
|
||||
"\nFault time:" + AbilityRuntime::TimeUtil::FormatTime("%Y/%m/%d-%H:%M:%S") + "\n";
|
||||
faultData.errorObject.message += "App main thread is not response!";
|
||||
faultData.faultType = FaultDataType::APP_FREEZE;
|
||||
int32_t pid = static_cast<int32_t>(getpid());
|
||||
if (isSixSecondEvent) {
|
||||
faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_6S;
|
||||
@@ -181,7 +183,6 @@ void AppfreezeInner::AppfreezeHandleOverReportCount(bool isSixSecondEvent)
|
||||
void AppfreezeInner::EnableFreezeSample(FaultData& newFaultData)
|
||||
{
|
||||
std::string eventName = newFaultData.errorObject.name;
|
||||
newFaultData.isInForeground = GetAppInForeground();
|
||||
if (eventName == AppFreezeType::THREAD_BLOCK_3S || eventName == AppFreezeType::LIFECYCLE_HALF_TIMEOUT) {
|
||||
OHOS::HiviewDFX::Watchdog::GetInstance().StartSample(HALF_DURATION, HALF_INTERVAL);
|
||||
TAG_LOGI(AAFwkTag::APPDFR, "start to sample freeze stack, eventName:%{public}s", eventName.c_str());
|
||||
@@ -278,7 +279,6 @@ int AppfreezeInner::AcquireStack(const FaultData& info, bool onlyMainThread)
|
||||
faultData.appfreezeInfo = it->appfreezeInfo;
|
||||
faultData.appRunningUniqueId = it->appRunningUniqueId;
|
||||
faultData.procStatm = it->procStatm;
|
||||
faultData.isInForeground = it->isInForeground;
|
||||
faultData.isEnableMainThreadSample = it->isEnableMainThreadSample;
|
||||
faultData.schedTime = it->schedTime;
|
||||
faultData.detectTime = it->detectTime;
|
||||
@@ -299,7 +299,6 @@ void AppfreezeInner::ThreadBlock(std::atomic_bool& isSixSecondEvent, uint64_t sc
|
||||
faultData.errorObject.message =
|
||||
"\nFault time:" + AbilityRuntime::TimeUtil::FormatTime("%Y/%m/%d-%H:%M:%S") + "\n";
|
||||
faultData.errorObject.message += "App main thread is not response!";
|
||||
faultData.faultType = FaultDataType::APP_FREEZE;
|
||||
bool onlyMainThread = false;
|
||||
int32_t pid = static_cast<int32_t>(getpid());
|
||||
faultData.pid = pid;
|
||||
|
||||
@@ -171,10 +171,6 @@ void Watchdog::SetBundleInfo(const std::string& bundleName, const std::string& b
|
||||
ChangeTimeOut(bundleName);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(cvMutex_);
|
||||
bundleName_ = bundleName;
|
||||
}
|
||||
}
|
||||
|
||||
void Watchdog::SetBackgroundStatus(const bool isInBackground)
|
||||
@@ -287,16 +283,13 @@ void Watchdog::ReportEvent()
|
||||
}
|
||||
|
||||
if (isInBackground_ && backgroundReportCount_.load() < BACKGROUND_REPORT_COUNT_MAX) {
|
||||
bool enableCheck = std::find(std::begin(CHECK_BACKGROUND_THREAD), std::end(CHECK_BACKGROUND_THREAD),
|
||||
bundleName_) != std::end(CHECK_BACKGROUND_THREAD);
|
||||
if (enableCheck) {
|
||||
backgroundReportCount_++;
|
||||
}
|
||||
backgroundReportCount_++;
|
||||
TAG_LOGI(AAFwkTag::APPDFR, "In Background, thread may be blocked in, not report time"
|
||||
"currTime: %{public}" PRIu64 ", lastTime: %{public}" PRIu64 ", enableCheck: %{public}d",
|
||||
static_cast<uint64_t>(now), static_cast<uint64_t>(lastWatchTime_), enableCheck);
|
||||
"currTime: %{public}" PRIu64 ", lastTime: %{public}" PRIu64 ", count: %{public}d",
|
||||
static_cast<uint64_t>(now), static_cast<uint64_t>(lastWatchTime_), backgroundReportCount_.load());
|
||||
return;
|
||||
}
|
||||
backgroundReportCount_++;
|
||||
|
||||
if (!needReport_) {
|
||||
return;
|
||||
|
||||
@@ -37,7 +37,8 @@ enum class FaultDataType {
|
||||
APP_FREEZE,
|
||||
CPU_LOAD,
|
||||
PERFORMANCE_CONTROL,
|
||||
RESOURCE_CONTROL
|
||||
RESOURCE_CONTROL,
|
||||
BACKGROUND_WARNING
|
||||
};
|
||||
|
||||
enum AppStatus {
|
||||
@@ -58,6 +59,7 @@ public:
|
||||
static constexpr char APP_INPUT_BLOCK[] = "APP_INPUT_BLOCK";
|
||||
static constexpr char BUSSINESS_THREAD_BLOCK_3S[] = "BUSSINESS_THREAD_BLOCK_3S";
|
||||
static constexpr char BUSSINESS_THREAD_BLOCK_6S[] = "BUSSINESS_THREAD_BLOCK_6S";
|
||||
static constexpr char BACKGROUND_WARNING[] = "BACKGROUND_WARNING";
|
||||
};
|
||||
/**
|
||||
* @struct FaultData
|
||||
|
||||
@@ -129,7 +129,6 @@ private:
|
||||
std::condition_variable cvWatchdog_;
|
||||
static std::shared_ptr<EventHandler> appMainHandler_;
|
||||
int64_t lastWatchTime_ = 0;
|
||||
std::string bundleName_;
|
||||
bool isSystemApp_ = true;
|
||||
};
|
||||
} // namespace AppExecFwk
|
||||
|
||||
@@ -108,6 +108,8 @@ public:
|
||||
void ReportAppFreezeSysEvents(int32_t pid, const std::string& bundleName);
|
||||
void RegisterAppKillTime(int32_t pid, uint64_t killTime);
|
||||
void InitWarningCpuInfo(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo);
|
||||
bool CheckInBackGround(const FaultData &faultData);
|
||||
bool CheckAppfreezeHappend(int32_t pid, const std::string& eventName);
|
||||
|
||||
private:
|
||||
struct PeerBinderInfo {
|
||||
|
||||
@@ -835,7 +835,8 @@ bool AppfreezeManager::IsNeedIgnoreFreezeEvent(int32_t pid, const std::string& e
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (errorName == "THREAD_BLOCK_3S") {
|
||||
if (errorName == AppFreezeType::THREAD_BLOCK_3S ||
|
||||
errorName == AppFreezeType::BUSSINESS_THREAD_BLOCK_3S) {
|
||||
return false;
|
||||
}
|
||||
SetFreezeState(pid, AppFreezeState::APPFREEZE_STATE_FREEZE, errorName);
|
||||
@@ -1003,5 +1004,26 @@ std::string AppfreezeManager::GetFirstLine(const std::string &path)
|
||||
inFile.close();
|
||||
return firstLine;
|
||||
}
|
||||
|
||||
bool AppfreezeManager::CheckInBackGround(const FaultData &faultData)
|
||||
{
|
||||
return faultData.errorObject.name == AppFreezeType::THREAD_BLOCK_6S &&
|
||||
!faultData.isInForeground;
|
||||
}
|
||||
|
||||
bool AppfreezeManager::CheckAppfreezeHappend(int32_t pid, const std::string& eventName)
|
||||
{
|
||||
if (eventName == AppFreezeType::LIFECYCLE_TIMEOUT || eventName == AppFreezeType::APP_INPUT_BLOCK ||
|
||||
eventName == AppFreezeType::THREAD_BLOCK_6S || eventName == AppFreezeType::THREAD_BLOCK_3S ||
|
||||
eventName == AppFreezeType::BUSSINESS_THREAD_BLOCK_3S ||
|
||||
eventName == AppFreezeType::BUSSINESS_THREAD_BLOCK_6S) {
|
||||
if (IsNeedIgnoreFreezeEvent(pid, eventName)) {
|
||||
TAG_LOGE(AAFwkTag::APPDFR, "appFreeze happend, pid:%{public}d, eventName:%{public}s",
|
||||
pid, eventName.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace AAFwk
|
||||
} // namespace OHOS
|
||||
@@ -7319,7 +7319,8 @@ void AppMgrServiceInner::AppRecoveryNotifyApp(int32_t pid, const std::string& bu
|
||||
void AppMgrServiceInner::ParseInfoToAppfreeze(const FaultData &faultData, int32_t pid, int32_t uid,
|
||||
const std::string &bundleName, const std::string &processName, const bool isOccurException)
|
||||
{
|
||||
if (faultData.faultType == FaultDataType::APP_FREEZE) {
|
||||
if (faultData.faultType == FaultDataType::APP_FREEZE ||
|
||||
faultData.faultType == FaultDataType::BACKGROUND_WARNING) {
|
||||
AppfreezeManager::AppInfo info = {
|
||||
.isOccurException = isOccurException,
|
||||
.pid = pid,
|
||||
@@ -7358,7 +7359,9 @@ int AppMgrServiceInner::GetExceptionTimerId(const FaultData &faultData, const st
|
||||
TAG_LOGI(AAFwkTag::APPMGR, "Ffrt Exception faultData: %{public}s,pid: %{public}d "
|
||||
"will exit because"" %{public}s", bundleName.c_str(), pid,
|
||||
innerService->FaultTypeToString(faultData.faultType).c_str());
|
||||
innerService->KillProcessByPid(pid, faultData.errorObject.name);
|
||||
std::string reason = AppExecFwk::AppfreezeManager::GetInstance()->CheckInBackGround(faultData) ?
|
||||
AppFreezeType::BACKGROUND_WARNING : faultData.errorObject.name;
|
||||
innerService->KillProcessByPid(pid, reason);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -7448,7 +7451,7 @@ int32_t AppMgrServiceInner::NotifyAppFault(const FaultData &faultData)
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
if (faultData.faultType == FaultDataType::APP_FREEZE) {
|
||||
if (faultData.faultType == FaultDataType::APP_FREEZE || faultData.faultType == FaultDataType::BACKGROUND_WARNING) {
|
||||
if (CheckAppFault(appRecord, faultData)) {
|
||||
return ERR_OK;
|
||||
}
|
||||
@@ -7457,14 +7460,9 @@ int32_t AppMgrServiceInner::NotifyAppFault(const FaultData &faultData)
|
||||
AppRecoveryNotifyApp(pid, bundleName, FaultDataType::APP_FREEZE, "recoveryTimeout");
|
||||
}
|
||||
}
|
||||
if (eventName == AppFreezeType::LIFECYCLE_TIMEOUT || eventName == AppFreezeType::APP_INPUT_BLOCK ||
|
||||
eventName == AppFreezeType::THREAD_BLOCK_6S || eventName == AppFreezeType::THREAD_BLOCK_3S ||
|
||||
eventName == AppFreezeType::BUSSINESS_THREAD_BLOCK_3S || eventName == AppFreezeType::BUSSINESS_THREAD_BLOCK_6S) {
|
||||
if (AppExecFwk::AppfreezeManager::GetInstance()->IsNeedIgnoreFreezeEvent(pid, eventName)) {
|
||||
TAG_LOGE(AAFwkTag::APPDFR, "appFreeze happend, pid:%{public}d, eventName:%{public}s",
|
||||
pid, eventName.c_str());
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
if (AppExecFwk::AppfreezeManager::GetInstance()->CheckAppfreezeHappend(pid, eventName)) {
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
if (appRunningManager_ && eventName.find("THREAD_BLOCK_") != std::string::npos) {
|
||||
@@ -7522,7 +7520,9 @@ int32_t AppMgrServiceInner::KillFaultApp(int32_t pid, const std::string &bundleN
|
||||
uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
AppExecFwk::AppfreezeManager::GetInstance()->RegisterAppKillTime(pid, now);
|
||||
innerService->KillProcessByPid(pid, faultData.errorObject.name);
|
||||
std::string reason = AppExecFwk::AppfreezeManager::GetInstance()->CheckInBackGround(faultData) ?
|
||||
AppFreezeType::BACKGROUND_WARNING : faultData.errorObject.name;
|
||||
innerService->KillProcessByPid(pid, reason);
|
||||
return;
|
||||
};
|
||||
constexpr int32_t waitTime = 3500;
|
||||
@@ -7549,7 +7549,7 @@ void AppMgrServiceInner::TimeoutNotifyApp(int32_t pid, int32_t uid,
|
||||
#else
|
||||
KillFaultApp(pid, bundleName, faultData, isNeedExit);
|
||||
#endif
|
||||
if (faultData.faultType == FaultDataType::APP_FREEZE) {
|
||||
if (faultData.faultType == FaultDataType::APP_FREEZE || faultData.faultType == FaultDataType::BACKGROUND_WARNING) {
|
||||
AppfreezeManager::AppInfo info = {
|
||||
.pid = pid,
|
||||
.uid = uid,
|
||||
@@ -7589,7 +7589,8 @@ int32_t AppMgrServiceInner::TransformedNotifyAppFault(const AppFaultDataBySA &fa
|
||||
std::to_string(pid) + "-" + std::to_string(SystemTimeMillisecond());
|
||||
}
|
||||
const int64_t timeout = 1000;
|
||||
if (faultData.faultType == FaultDataType::APP_FREEZE) {
|
||||
if (faultData.faultType == FaultDataType::APP_FREEZE ||
|
||||
faultData.faultType == FaultDataType::BACKGROUND_WARNING) {
|
||||
if (!AppExecFwk::AppfreezeManager::GetInstance()->IsHandleAppfreeze(bundleName) || record->IsDebugging()) {
|
||||
return ERR_OK;
|
||||
}
|
||||
@@ -7708,6 +7709,9 @@ std::string AppMgrServiceInner::FaultTypeToString(AppExecFwk::FaultDataType type
|
||||
case AppExecFwk::FaultDataType::RESOURCE_CONTROL:
|
||||
typeStr = "RESOURCE_CONTROL";
|
||||
break;
|
||||
case AppExecFwk::FaultDataType::BACKGROUND_WARNING:
|
||||
typeStr = "BACKGROUND_WARNING";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -436,5 +436,24 @@ HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_GetFirstLine_001, TestSize.L
|
||||
appfreezeManager->GetFirstLine("/data/log/test");
|
||||
EXPECT_TRUE(appfreezeManager != nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AppfreezeManagerTest_CheckAppfreezeHappend_001
|
||||
* @tc.desc: add testcase
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_CheckAppfreezeHappend_001, TestSize.Level1)
|
||||
{
|
||||
bool ret = appfreezeManager->CheckAppfreezeHappend(getpid(), "CheckAppfreezeHappend");
|
||||
EXPECT_EQ(ret, false);
|
||||
ret = appfreezeManager->CheckAppfreezeHappend(getpid(), "BUSSINESS_THREAD_BLOCK_3S");
|
||||
EXPECT_EQ(ret, false);
|
||||
ret = appfreezeManager->CheckAppfreezeHappend(getpid(), "BUSSINESS_THREAD_BLOCK_6S");
|
||||
EXPECT_EQ(ret, true);
|
||||
appfreezeManager->CheckAppfreezeHappend(getpid(), "LIFECYCLE_TIMEOUT");
|
||||
appfreezeManager->CheckAppfreezeHappend(getpid(), "THREAD_BLOCK_6S");
|
||||
appfreezeManager->CheckAppfreezeHappend(getpid(), "APP_INPUT_BLOCK");
|
||||
appfreezeManager->CheckAppfreezeHappend(getpid(), "THREAD_BLOCK_3S");
|
||||
}
|
||||
} // namespace AppExecFwk
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -539,7 +539,6 @@ HWTEST_F(WatchdogTest, WatchdogTest_SetHiTraceChainId_001, TestSize.Level1)
|
||||
HWTEST_F(WatchdogTest, WatchdogTest_CheckBgThread_000, TestSize.Level1)
|
||||
{
|
||||
watchdog_->isInBackground_.store(true);
|
||||
watchdog_->bundleName_ = "com.ohos.sceneboard";
|
||||
watchdog_->lastWatchTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::
|
||||
system_clock::now().time_since_epoch()).count() - 3000; // 3000: test value
|
||||
int count = 5; // 5: test value
|
||||
|
||||
Reference in New Issue
Block a user