diff --git a/frameworks/native/appkit/dfr/appfreeze_inner.cpp b/frameworks/native/appkit/dfr/appfreeze_inner.cpp index 824d5a0e0968db6cbcd060783996471efae09553..fa01497060f47b6dd6ad7a7935b50cac047af2c5 100644 --- a/frameworks/native/appkit/dfr/appfreeze_inner.cpp +++ b/frameworks/native/appkit/dfr/appfreeze_inner.cpp @@ -273,12 +273,20 @@ int AppfreezeInner::AcquireStack(const FaultData& info, bool onlyMainThread) faultData.procStatm = it->procStatm; faultData.isInForeground = it->isInForeground; faultData.isEnableMainThreadSample = it->isEnableMainThreadSample; + faultData.schedTime = it->schedTime; + faultData.detectTime = it->detectTime; + faultData.appStatus = it->appStatus; + faultData.samplerStartTime = it->samplerStartTime; + faultData.samplerFinishTime = it->samplerFinishTime; + faultData.samplerCount = it->samplerCount; + faultData.pid = it->pid; ChangeFaultDateInfo(faultData, msgContent); } return 0; } -void AppfreezeInner::ThreadBlock(std::atomic_bool& isSixSecondEvent) +void AppfreezeInner::ThreadBlock(std::atomic_bool& isSixSecondEvent, uint64_t schedTime, + uint64_t now, bool isInBackground) { FaultData faultData; faultData.errorObject.message = @@ -287,10 +295,16 @@ void AppfreezeInner::ThreadBlock(std::atomic_bool& isSixSecondEvent) faultData.faultType = FaultDataType::APP_FREEZE; bool onlyMainThread = false; int32_t pid = static_cast(getpid()); + faultData.pid = pid; + faultData.schedTime = schedTime; + faultData.detectTime = now; + faultData.appStatus = isInBackground ? AppStatus::APP_STATUS_BACKGROUND : AppStatus::APP_STATUS_FOREGROUND; if (isSixSecondEvent) { faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_6S; onlyMainThread = true; + OHOS::HiviewDFX::Watchdog::GetInstance().GetSamplerResult(faultData.samplerStartTime, + faultData.samplerFinishTime, faultData.samplerCount); #ifdef APP_NO_RESPONSE_DIALOG isSixSecondEvent.store(false); #endif diff --git a/frameworks/native/appkit/dfr/watchdog.cpp b/frameworks/native/appkit/dfr/watchdog.cpp index 8026e3370c3f5860f13449d27fd9e357714a8023..aefd225e838b78a33d8e7798d26f1370b01640ab 100644 --- a/frameworks/native/appkit/dfr/watchdog.cpp +++ b/frameworks/native/appkit/dfr/watchdog.cpp @@ -313,7 +313,7 @@ void Watchdog::ReportEvent() SetHiTraceChainId(); } #endif - AppExecFwk::AppfreezeInner::GetInstance()->ThreadBlock(isSixSecondEvent_); + AppExecFwk::AppfreezeInner::GetInstance()->ThreadBlock(isSixSecondEvent_, 0, now, isInBackground_); } } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/app_manager/include/appmgr/fault_data.h b/interfaces/inner_api/app_manager/include/appmgr/fault_data.h index 6a27206cc19a39fa56320fbc6060e9dbe4757f90..bfe588b0ae0dd908a3bf662494a0b352c0c48142 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/fault_data.h +++ b/interfaces/inner_api/app_manager/include/appmgr/fault_data.h @@ -40,6 +40,12 @@ enum class FaultDataType { RESOURCE_CONTROL }; +enum AppStatus { + APP_STATUS_UNKNOW = -1, + APP_STATUS_FOREGROUND = 0, + APP_STATUS_BACKGROUND = 1 +}; + class AppFreezeType { public: static constexpr char LIFECYCLE_HALF_TIMEOUT[] = "LIFECYCLE_HALF_TIMEOUT"; @@ -73,8 +79,15 @@ struct FaultData : public Parcelable { bool needKillProcess = true; uint32_t state = 0; int32_t eventId = -1; + uint64_t schedTime = 0; + uint64_t detectTime = 0; + int32_t pid = -1; int32_t tid = -1; uint32_t stuckTimeout = 0; + int32_t appStatus = -1; + uint64_t samplerStartTime = 0; + uint64_t samplerFinishTime = 0; + int32_t samplerCount = -1; sptr token = nullptr; std::string appfreezeInfo; std::string appRunningUniqueId; @@ -104,6 +117,9 @@ struct AppFaultDataBySA : public Parcelable { int32_t pid = -1; uint32_t state = 0; int32_t eventId = -1; + uint64_t schedTime = 0; + uint64_t detectTime = 0; + int32_t appStatus = -1; sptr token = nullptr; std::string timeoutMarkers; std::string appfreezeInfo; diff --git a/interfaces/inner_api/app_manager/src/appmgr/fault_data.cpp b/interfaces/inner_api/app_manager/src/appmgr/fault_data.cpp index d2f456df8e97e4ced83021e625acace16850ac92..e7df65f355949b37f7f5cb60b5a171df89c0307d 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/fault_data.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/fault_data.cpp @@ -21,38 +21,39 @@ namespace OHOS { namespace AppExecFwk { +#define RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(expr, log) \ + do { \ + if ((expr)) { \ + TAG_LOGE(AAFwkTag::APPMGR, log); \ + return false; \ + } \ + } while (0) + +#define RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(expr, log, arg) \ + do { \ + if ((expr)) { \ + TAG_LOGE(AAFwkTag::APPMGR, log, arg); \ + return false; \ + } \ + } while (0) + bool FaultData::ReadFromParcel(Parcel &parcel) { std::string strValue; - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "Name read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "Name read string failed."); errorObject.name = strValue; - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "Message read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "Message read string failed."); errorObject.message = strValue; - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "Stack read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "Stack read string failed."); errorObject.stack = strValue; int type = 0; - if (!parcel.ReadInt32(type)) { - TAG_LOGE(AAFwkTag::APPMGR, "FaultType read int32 failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadInt32(type), "FaultType read int32 failed."); faultType = static_cast(type); - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "TimeoutMarkers read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "TimeoutMarkers read string failed."); timeoutMarkers = strValue; waitSaveState = parcel.ReadBool(); @@ -61,15 +62,20 @@ bool FaultData::ReadFromParcel(Parcel &parcel) needKillProcess = parcel.ReadBool(); state = parcel.ReadUint32(); eventId = parcel.ReadInt32(); + schedTime = parcel.ReadUint64(); + detectTime = parcel.ReadUint64(); + appStatus = parcel.ReadInt32(); + samplerStartTime = parcel.ReadUint64(); + samplerFinishTime = parcel.ReadUint64(); + samplerCount = parcel.ReadInt32(); + pid = parcel.ReadInt32(); tid = parcel.ReadInt32(); stuckTimeout = parcel.ReadUint32(); if (parcel.ReadBool()) { token = (static_cast(&parcel))->ReadRemoteObject(); } - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "AppfreezeInfo read string failed."); - return false; - } + + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "AppfreezeInfo read string failed."); appfreezeInfo = strValue; return ReadContent(parcel); } @@ -77,15 +83,10 @@ bool FaultData::ReadFromParcel(Parcel &parcel) bool FaultData::ReadContent(Parcel &parcel) { std::string strValue; - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "AppRunningUniqueId read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "AppRunningUniqueId read string failed."); appRunningUniqueId = strValue; - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "ProcStatm read string failed."); - return false; - } + + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "ProcStatm read string failed."); procStatm = strValue; isInForeground = parcel.ReadBool(); @@ -105,16 +106,12 @@ FaultData *FaultData::Unmarshalling(Parcel &parcel) bool FaultData::WriteContent(Parcel &parcel) const { - if (!parcel.WriteUint32(stuckTimeout)) { - TAG_LOGE(AAFwkTag::APPMGR, "stuckTimeout [%{public}u] write uint32 failed.", stuckTimeout); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteUint32(stuckTimeout), + "stuckTimeout [%{public}u] write uint32 failed.", stuckTimeout + ); if (token == nullptr) { - if (!parcel.WriteBool(false)) { - TAG_LOGE(AAFwkTag::APPMGR, "Token falge [false] write bool failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.WriteBool(false), "Token falge [false] write bool failed."); } else { if (!parcel.WriteBool(true) || !(static_cast(&parcel))->WriteRemoteObject(token)) { TAG_LOGE(AAFwkTag::APPMGR, "Token falge [true] write bool failed."); @@ -122,97 +119,105 @@ bool FaultData::WriteContent(Parcel &parcel) const } } - if (!parcel.WriteString(appfreezeInfo)) { - TAG_LOGE(AAFwkTag::APPMGR, "AppfreezeInfo [%{public}s] write string failed.", appfreezeInfo.c_str()); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(appfreezeInfo), + "AppfreezeInfo [%{public}s] write string failed.", appfreezeInfo.c_str() + ); - if (!parcel.WriteString(appRunningUniqueId)) { - TAG_LOGE(AAFwkTag::APPMGR, "AppRunningUniqueId [%{public}s] write string failed.", appRunningUniqueId.c_str()); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(appRunningUniqueId), + "AppRunningUniqueId [%{public}s] write string failed.", appRunningUniqueId.c_str() + ); - if (!parcel.WriteString(procStatm)) { - TAG_LOGE(AAFwkTag::APPMGR, "ProcStatm [%{public}s] write string failed.", procStatm.c_str()); - return false; - } - - if (!parcel.WriteBool(isInForeground)) { - TAG_LOGE(AAFwkTag::APPMGR, "InForeground [%{public}d] write bool failed.", isInForeground); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(procStatm), + "ProcStatm [%{public}s] write string failed.", procStatm.c_str() + ); - if (!parcel.WriteBool(isEnableMainThreadSample)) { - TAG_LOGE(AAFwkTag::APPMGR, "isEnableMainThreadSample [%{public}d] write bool failed.", - isEnableMainThreadSample); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(isInForeground), + "InForeground [%{public}d] write bool failed.", isInForeground + ); + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(isEnableMainThreadSample), + "isEnableMainThreadSample [%{public}d] write bool failed.", isEnableMainThreadSample + ); return true; } bool FaultData::Marshalling(Parcel &parcel) const { - if (!parcel.WriteString(errorObject.name)) { - TAG_LOGE(AAFwkTag::APPMGR, "Name [%{public}s] write string failed.", errorObject.name.c_str()); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(errorObject.name), + "Name [%{public}s] write string failed.", errorObject.name.c_str() + ); - if (!parcel.WriteString(errorObject.message)) { - TAG_LOGE(AAFwkTag::APPMGR, "Message [%{public}s] write string failed.", errorObject.message.c_str()); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(errorObject.message), + "Message [%{public}s] write string failed.", errorObject.message.c_str() + ); - if (!parcel.WriteString(errorObject.stack)) { - TAG_LOGE(AAFwkTag::APPMGR, "Stack [%{public}s] write string failed.", errorObject.stack.c_str()); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(errorObject.stack), + "Stack [%{public}s] write string failed.", errorObject.stack.c_str() + ); - if (!parcel.WriteInt32(static_cast(faultType))) { - TAG_LOGE(AAFwkTag::APPMGR, "FaultType [%{public}d] write int32 failed.", static_cast(faultType)); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteInt32(static_cast(faultType)), + "FaultType [%{public}d] write int32 failed.", static_cast(faultType) + ); - if (!parcel.WriteString(timeoutMarkers)) { - TAG_LOGE(AAFwkTag::APPMGR, "TimeoutMarkers [%{public}s] write string failed.", timeoutMarkers.c_str()); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(timeoutMarkers), + "TimeoutMarkers [%{public}s] write string failed.", timeoutMarkers.c_str() + ); - if (!parcel.WriteBool(waitSaveState)) { - TAG_LOGE(AAFwkTag::APPMGR, "WaitSaveState [%{public}s] write bool failed.", waitSaveState ? "true" : "false"); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(waitSaveState), + "WaitSaveState [%{public}s] write bool failed.", waitSaveState ? "true" : "false" + ); - if (!parcel.WriteBool(notifyApp)) { - TAG_LOGE(AAFwkTag::APPMGR, "NotifyApp [%{public}s] write bool failed.", notifyApp ? "true" : "false"); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(notifyApp), + "NotifyApp [%{public}s] write bool failed.", notifyApp ? "true" : "false" + ); - if (!parcel.WriteBool(forceExit)) { - TAG_LOGE(AAFwkTag::APPMGR, "ForceExit [%{public}s] write bool failed.", forceExit ? "true" : "false"); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(forceExit), + "ForceExit [%{public}s] write bool failed.", forceExit ? "true" : "false" + ); - if (!parcel.WriteBool(needKillProcess)) { - TAG_LOGE(AAFwkTag::APPMGR, "needKillProcess [%{public}s] write bool failed.", - needKillProcess ? "true" : "false"); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(needKillProcess), + "needKillProcess [%{public}s] write bool failed.", needKillProcess ? "true" : "false" + ); - if (!parcel.WriteUint32(state)) { - TAG_LOGE(AAFwkTag::APPMGR, "State [%{public}u] write uint32 failed.", state); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteUint32(state), + "State [%{public}u] write uint32 failed.", state + ); - if (!parcel.WriteInt32(eventId)) { - TAG_LOGE(AAFwkTag::APPMGR, "EventId [%{public}u] write int32 failed.", eventId); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteInt32(eventId), + "EventId [%{public}u] write int32 failed.", eventId + ); - if (!parcel.WriteInt32(tid)) { - TAG_LOGE(AAFwkTag::APPMGR, "Tid [%{public}u] write int32 failed.", tid); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteUint64(schedTime), + "SchedTime [%{public}" PRIu64 "] write uint64 failed.", schedTime + ); + + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteUint64(detectTime), + "DetectTime [%{public}" PRIu64 "] write uint64 failed.", detectTime + ); + + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteInt32(appStatus), + "AppStatus [%{public}d] write int32 failed.", appStatus + ); + + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteUint64(samplerStartTime), + "SamplerStartTime [%{public}" PRIu64 "] write uint64 failed.", samplerStartTime + ); + + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteUint64(samplerFinishTime), + "SamplerFinishTime [%{public}" PRIu64"] write uint64 failed.", samplerFinishTime + ); + + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteInt32(samplerCount), + "SamplerCount [%{public}d] write int32 failed.", samplerCount + ); + + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteInt32(pid), + "Pid [%{public}u] write int32 failed.", pid + ); + + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteInt32(tid), + "Tid [%{public}u] write int32 failed.", tid + ); return WriteContent(parcel); } @@ -220,40 +225,22 @@ bool FaultData::Marshalling(Parcel &parcel) const bool AppFaultDataBySA::ReadFromParcel(Parcel &parcel) { std::string strValue; - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "Name read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "Name read string failed."); errorObject.name = strValue; - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "Message read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "Message read string failed."); errorObject.message = strValue; - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "Stack read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "Stack read string failed."); errorObject.stack = strValue; int type = 0; - if (!parcel.ReadInt32(type)) { - TAG_LOGE(AAFwkTag::APPMGR, "Type read int32 failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadInt32(type), "Type read int32 failed."); faultType = static_cast(type); - if (!parcel.ReadInt32(pid)) { - TAG_LOGE(AAFwkTag::APPMGR, "Pid read int32 failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadInt32(pid), "Pid read int32 failed."); - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "TimeoutMarkers read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "TimeoutMarkers read string failed."); timeoutMarkers = strValue; waitSaveState = parcel.ReadBool(); @@ -262,14 +249,14 @@ bool AppFaultDataBySA::ReadFromParcel(Parcel &parcel) needKillProcess = parcel.ReadBool(); state = parcel.ReadUint32(); eventId = parcel.ReadInt32(); + schedTime = parcel.ReadUint64(); + detectTime = parcel.ReadUint64(); + appStatus = parcel.ReadInt32(); if (parcel.ReadBool()) { token = (static_cast(&parcel))->ReadRemoteObject(); } - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "AppfreezeInfo read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "AppfreezeInfo read string failed."); appfreezeInfo = strValue; return ReadContent(parcel); } @@ -277,16 +264,10 @@ bool AppFaultDataBySA::ReadFromParcel(Parcel &parcel) bool AppFaultDataBySA::ReadContent(Parcel &parcel) { std::string strValue; - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "AppRunningUniqueId read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "AppRunningUniqueId read string failed."); appRunningUniqueId = strValue; - if (!parcel.ReadString(strValue)) { - TAG_LOGE(AAFwkTag::APPMGR, "ProcStatm read string failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.ReadString(strValue), "ProcStatm read string failed."); procStatm = strValue; isInForeground = parcel.ReadBool(); isEnableMainThreadSample = parcel.ReadBool(); @@ -306,10 +287,7 @@ AppFaultDataBySA *AppFaultDataBySA::Unmarshalling(Parcel &parcel) bool AppFaultDataBySA::WriteContent(Parcel &parcel) const { if (token == nullptr) { - if (!parcel.WriteBool(false)) { - TAG_LOGE(AAFwkTag::APPMGR, "Token falge [false] write bool failed."); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_IF_TRUE(!parcel.WriteBool(false), "Token falge [false] write bool failed."); } else { if (!parcel.WriteBool(true) || !(static_cast(&parcel))->WriteRemoteObject(token)) { TAG_LOGE(AAFwkTag::APPMGR, "Token falge [true] write bool failed."); @@ -317,32 +295,25 @@ bool AppFaultDataBySA::WriteContent(Parcel &parcel) const } } - if (!parcel.WriteString(appfreezeInfo)) { - TAG_LOGE(AAFwkTag::APPMGR, "AppfreezeInfo [%{public}s] write string failed.", appfreezeInfo.c_str()); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(appfreezeInfo), + "AppfreezeInfo [%{public}s] write string failed.", appfreezeInfo.c_str() + ); - if (!parcel.WriteString(appRunningUniqueId)) { - TAG_LOGE(AAFwkTag::APPMGR, "AppRunningUniqueId [%{public}s] write string failed.", appRunningUniqueId.c_str()); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(appRunningUniqueId), + "AppRunningUniqueId [%{public}s] write string failed.", appRunningUniqueId.c_str() + ); - if (!parcel.WriteString(procStatm)) { - TAG_LOGE(AAFwkTag::APPMGR, "ProcStatm [%{public}s] write string failed.", procStatm.c_str()); - return false; - } - - if (!parcel.WriteBool(isInForeground)) { - TAG_LOGE(AAFwkTag::APPMGR, "InForeground [%{public}d] write bool failed.", isInForeground); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(procStatm), + "ProcStatm [%{public}s] write string failed.", procStatm.c_str() + ); - if (!parcel.WriteBool(isEnableMainThreadSample)) { - TAG_LOGE(AAFwkTag::APPMGR, "isEnableMainThreadSample [%{public}d] write bool failed.", - isEnableMainThreadSample); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(isInForeground), + "InForeground [%{public}d] write bool failed.", isInForeground + ); + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(isEnableMainThreadSample), + "isEnableMainThreadSample [%{public}d] write bool failed.", isEnableMainThreadSample + ); return true; } @@ -352,71 +323,70 @@ bool AppFaultDataBySA::Marshalling(Parcel &parcel) const return false; } - if (!parcel.WriteInt32(static_cast(faultType))) { - TAG_LOGE(AAFwkTag::APPMGR, "FaultType [%{public}d] write int32 failed.", static_cast(faultType)); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteInt32(static_cast(faultType)), + "FaultType [%{public}d] write int32 failed.", static_cast(faultType) + ); - if (!parcel.WriteInt32(pid)) { - TAG_LOGE(AAFwkTag::APPMGR, "Pid [%{public}d] write int32 failed.", static_cast(pid)); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteInt32(pid), + "Pid [%{public}d] write int32 failed.", static_cast(pid) + ); - if (!parcel.WriteString(timeoutMarkers)) { - TAG_LOGE(AAFwkTag::APPMGR, "TimeoutMarkers [%{public}s] write string failed.", timeoutMarkers.c_str()); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(timeoutMarkers), + "TimeoutMarkers [%{public}s] write string failed.", timeoutMarkers.c_str() + ); - if (!parcel.WriteBool(waitSaveState)) { - TAG_LOGE(AAFwkTag::APPMGR, "WaitSaveState [%{public}s] write bool failed.", waitSaveState ? "true" : "false"); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(waitSaveState), + "WaitSaveState [%{public}s] write bool failed.", waitSaveState ? "true" : "false" + ); - if (!parcel.WriteBool(notifyApp)) { - TAG_LOGE(AAFwkTag::APPMGR, "NotifyApp [%{public}s] write bool failed.", notifyApp ? "true" : "false"); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(notifyApp), + "NotifyApp [%{public}s] write bool failed.", notifyApp ? "true" : "false" + ); - if (!parcel.WriteBool(forceExit)) { - TAG_LOGE(AAFwkTag::APPMGR, "ForceExit [%{public}s] write bool failed.", forceExit ? "true" : "false"); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(forceExit), + "ForceExit [%{public}s] write bool failed.", forceExit ? "true" : "false" + ); - if (!parcel.WriteBool(needKillProcess)) { - TAG_LOGE(AAFwkTag::APPMGR, "needKillProcess [%{public}s] write bool failed.", - needKillProcess ? "true" : "false"); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteBool(needKillProcess), + "needKillProcess [%{public}s] write bool failed.", needKillProcess ? "true" : "false" + ); - if (!parcel.WriteUint32(state)) { - TAG_LOGE(AAFwkTag::APPMGR, "State [%{public}u] write uint32 failed.", state); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteUint32(state), + "State [%{public}u] write uint32 failed.", state + ); - if (!parcel.WriteInt32(eventId)) { - TAG_LOGE(AAFwkTag::APPMGR, "EventId [%{public}u] write int32 failed.", eventId); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteInt32(eventId), + "EventId [%{public}u] write int32 failed.", eventId + ); + + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteUint64(schedTime), + "SchedTime [%{public}" PRIu64 "] write uint64 failed.", schedTime + ); + + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteUint64(detectTime), + "DetectTime [%{public}" PRIu64 "] write uint64 failed.", detectTime + ); + + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteInt32(appStatus), + "AppStatus [%{public}d] write int32 failed.", appStatus + ); return WriteContent(parcel); } bool AppFaultDataBySA::WriteErrorObject(Parcel &parcel) const { - if (!parcel.WriteString(errorObject.name)) { - TAG_LOGE(AAFwkTag::APPMGR, "Name [%{public}s] write string failed.", errorObject.name.c_str()); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(errorObject.name), + "Name [%{public}s] write string failed.", errorObject.name.c_str() + ); - if (!parcel.WriteString(errorObject.message)) { - TAG_LOGE(AAFwkTag::APPMGR, "Message [%{public}s] write string failed.", errorObject.message.c_str()); - return false; - } - - if (!parcel.WriteString(errorObject.stack)) { - TAG_LOGE(AAFwkTag::APPMGR, "Stack [%{public}s] write string failed.", errorObject.stack.c_str()); - return false; - } + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(errorObject.message), + "Message [%{public}s] write string failed.", errorObject.message.c_str() + ); + + RETURN_FALSE_AND_WRITE_LOG_WITH_ONE_ARG_IF_TRUE(!parcel.WriteString(errorObject.stack), + "Stack [%{public}s] write string failed.", errorObject.stack.c_str() + ); return true; } } // namespace AppExecFwk diff --git a/interfaces/kits/native/appkit/dfr/appfreeze_inner.h b/interfaces/kits/native/appkit/dfr/appfreeze_inner.h index cbe0ae531187c55b2cdfc5a9ad5bb19068d01dca..50fbcc983c2d59ffa61e7f7fe4f637d7e7d9df9f 100644 --- a/interfaces/kits/native/appkit/dfr/appfreeze_inner.h +++ b/interfaces/kits/native/appkit/dfr/appfreeze_inner.h @@ -41,7 +41,8 @@ public: static void DestroyInstance(); static void SetMainHandler(const std::shared_ptr& eventHandler); void SetApplicationInfo(const std::shared_ptr& applicationInfo); - void ThreadBlock(std::atomic_bool& isSixSecondEvent); + void ThreadBlock(std::atomic_bool& isSixSecondEvent, uint64_t schedTime = 0, + uint64_t now = 0, bool isInBackground = false); void ChangeFaultDateInfo(FaultData& faultData, const std::string& msgContent); void AppfreezeHandleOverReportCount(bool isSixSecondEvent); void GetMainHandlerDump(std::string& msgContent); diff --git a/services/appdfr/include/appfreeze_manager.h b/services/appdfr/include/appfreeze_manager.h index 6a7194d58027e9fa538320d9ad7faaf90dc31572..a18810aa450394a5e4d7ce4c8d5faefe2956be18 100644 --- a/services/appdfr/include/appfreeze_manager.h +++ b/services/appdfr/include/appfreeze_manager.h @@ -33,6 +33,14 @@ namespace OHOS { using AbilityRuntime::FreezeUtil; namespace AppExecFwk { +static const std::vector APP_FREEZE_EVENT_NAME = { + "THREAD_BLOCK_3S", + "THREAD_BLOCK_6S", + "APP_INPUUT_BLOCK", + "LIFECYCLE_HALF_TIMEOUT", + "LIFECYCLE_TIMEOUT", +}; + class AppfreezeManager : public std::enable_shared_from_this { public: struct AppInfo { @@ -71,6 +79,15 @@ public: std::string msg; }; + struct AppfreezeEventRecord { + uint64_t schedTime = 0; + uint64_t detectTime = 0; + uint64_t dumpStartTime = 0; + uint64_t dumpFinishTime = 0; + std::string dumpResult; + int32_t appStatus = -1; + }; + AppfreezeManager(); ~AppfreezeManager(); @@ -88,6 +105,8 @@ public: void RemoveDeathProcess(std::string bundleName); void ResetAppfreezeState(int32_t pid, const std::string& bundleName); bool IsValidFreezeFilter(int32_t pid, const std::string& bundleName); + 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); private: @@ -125,7 +144,8 @@ private: std::set GetBinderPeerPids(std::string& stack, AppfreezeManager::ParseBinderParam params, std::set& asyncPids, AppfreezeManager::TerminalBinder& terminalBinder) const; void FindStackByPid(std::string& msg, int pid) const; - std::string CatchJsonStacktrace(int pid, const std::string& faultType, const std::string& stack) const; + std::pair CatchJsonStacktrace( + int pid, const std::string& faultType, const std::string& stack) const; std::string CatcherStacktrace(int pid, const std::string& stack) const; FaultData GetFaultNotifyData(const FaultData& faultData, int pid); int AcquireStack(const FaultData& faultData, const AppInfo& appInfo, const std::string& memoryContent); @@ -139,6 +159,8 @@ private: void ClearOldInfo(); void CollectFreezeSysMemory(std::string& memoryContent); int MergeNotifyInfo(FaultData& faultNotifyData, const AppfreezeManager::AppInfo& appInfo); + void RecordAppFreezeBehavior(FaultData& faultData, uint64_t dumpStartTime, + uint64_t dumpFinishTime, const std::string& dumpResult); std::string ParseDecToHex(uint64_t id); std::string GetHitraceInfo(); void PerfStart(std::string eventName); @@ -157,6 +179,7 @@ private: int64_t perfTime = 0; static ffrt::mutex freezeInfoMutex_; static std::string appfreezeInfoPath_; + std::map> freezeEventMap_; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/services/appdfr/src/appfreeze_manager.cpp b/services/appdfr/src/appfreeze_manager.cpp index a7a2b0626dfd3d63a6de8f7847c24fd58fb5a698..749eede03e4acb26157c04c565de135e6db5f0ec 100644 --- a/services/appdfr/src/appfreeze_manager.cpp +++ b/services/appdfr/src/appfreeze_manager.cpp @@ -47,6 +47,7 @@ namespace OHOS { namespace AppExecFwk { namespace { constexpr char EVENT_UID[] = "UID"; +constexpr char KILL_EVENT_NAME[] = "APP_KILL"; #ifdef ABILITY_RUNTIME_HITRACE_ENABLE constexpr int32_t CHARACTER_WIDTH = 2; #endif @@ -54,6 +55,7 @@ constexpr int32_t CHARACTER_WIDTH = 2; constexpr int MAX_LAYER = 8; constexpr int FREEZEMAP_SIZE_MAX = 20; constexpr int FREEZE_TIME_LIMIT = 60000; +constexpr int FREEZE_EVENT_MAX_SIZE = 200; static constexpr uint8_t ARR_SIZE = 7; static constexpr uint8_t DECIMAL = 10; static constexpr uint8_t FREE_ASYNC_INDEX = 6; @@ -172,13 +174,18 @@ int AppfreezeManager::MergeNotifyInfo(FaultData& faultNotifyData, const Appfreez std::string catcherStack; faultNotifyData.errorObject.message += "\nCatche stack trace start time: " + AbilityRuntime::TimeUtil::DefaultCurrentTimeStr() + "\n"; + uint64_t dumpStartTime = AbilityRuntime::TimeUtil::CurrentTimeMillis(); + std::string resultMsg; if (faultNotifyData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT || faultNotifyData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT_WARNING) { catcherStack += CatcherStacktrace(appInfo.pid, faultNotifyData.errorObject.stack); } else { - catcherStack += CatchJsonStacktrace(appInfo.pid, faultNotifyData.errorObject.name, - faultNotifyData.errorObject.stack); + std::pair catchResult = + CatchJsonStacktrace(appInfo.pid, faultNotifyData.errorObject.name, faultNotifyData.errorObject.stack); + catcherStack += catchResult.first; + resultMsg += catchResult.second; } + uint64_t dumpFinishTime = AbilityRuntime::TimeUtil::CurrentTimeMillis(); std::string timeStamp = "Catche stack trace end time: " + AbilityRuntime::TimeUtil::DefaultCurrentTimeStr(); faultNotifyData.errorObject.stack = WriteToFile(fileName, catcherStack); if (appInfo.isOccurException) { @@ -193,9 +200,31 @@ int AppfreezeManager::MergeNotifyInfo(FaultData& faultNotifyData, const Appfreez } else { NotifyANR(faultNotifyData, appInfo, "", memoryContent); } + RecordAppFreezeBehavior(faultNotifyData, dumpStartTime, dumpFinishTime, resultMsg); return 0; } +void AppfreezeManager::RecordAppFreezeBehavior(FaultData& faultData, uint64_t dumpStartTime, + uint64_t dumpFinishTime, const std::string& resultMsg) +{ + std::string eventName = faultData.errorObject.name; + if (freezeEventMap_.size() > FREEZE_EVENT_MAX_SIZE) { + freezeEventMap_.clear(); + } + auto it = std::find(APP_FREEZE_EVENT_NAME.begin(), APP_FREEZE_EVENT_NAME.end(), eventName); + if (it != APP_FREEZE_EVENT_NAME.end()) { + freezeEventMap_[faultData.pid][eventName].schedTime = faultData.schedTime; + freezeEventMap_[faultData.pid][eventName].detectTime = faultData.detectTime; + freezeEventMap_[faultData.pid][eventName].dumpStartTime = dumpStartTime; + freezeEventMap_[faultData.pid][eventName].dumpFinishTime = dumpFinishTime; + freezeEventMap_[faultData.pid][eventName].dumpResult = resultMsg; + freezeEventMap_[faultData.pid][eventName].appStatus = faultData.appStatus; + freezeEventMap_[faultData.pid][KILL_EVENT_NAME].dumpStartTime = faultData.samplerStartTime; + freezeEventMap_[faultData.pid][KILL_EVENT_NAME].dumpFinishTime = faultData.samplerFinishTime; + freezeEventMap_[faultData.pid][KILL_EVENT_NAME].dumpResult = std::to_string(faultData.samplerCount); + } +} + int AppfreezeManager::AppfreezeHandleWithStack(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo) { TAG_LOGW(AAFwkTag::APPDFR, "NotifyAppFaultTask called, eventName:%{public}s, bundleName:%{public}s, " @@ -210,6 +239,13 @@ int AppfreezeManager::AppfreezeHandleWithStack(const FaultData& faultData, const faultNotifyData.errorObject.stack = faultData.errorObject.stack; faultNotifyData.faultType = FaultDataType::APP_FREEZE; faultNotifyData.eventId = faultData.eventId; + faultNotifyData.schedTime = faultData.schedTime; + faultNotifyData.detectTime = faultData.detectTime; + faultNotifyData.appStatus = faultData.appStatus; + faultNotifyData.samplerStartTime = faultData.samplerStartTime; + faultNotifyData.samplerFinishTime = faultData.samplerFinishTime; + faultNotifyData.samplerCount = faultData.samplerCount; + faultNotifyData.pid = faultData.pid; faultNotifyData.tid = faultData.tid; faultNotifyData.appfreezeInfo = faultData.appfreezeInfo; faultNotifyData.appRunningUniqueId = faultData.appRunningUniqueId; @@ -265,11 +301,9 @@ int AppfreezeManager::LifecycleTimeoutHandle(const ParamInfo& info, FreezeUtil:: TAG_LOGW(AAFwkTag::APPDFR, "hisysevent write HIVIEW_HALF_FREEZE_LOG, pid:%{public}d, packageName:%{public}s," " ret:%{public}d", info.pid, info.bundleName.c_str(), ret); } - TAG_LOGD(AAFwkTag::APPDFR, "called %{public}s, name_ %{public}s", info.bundleName.c_str(), name_.c_str()); HITRACE_METER_FMT(HITRACE_TAG_APP, "LifecycleTimeoutHandle:%{public}s bundleName:%{public}s", info.eventName.c_str(), info.bundleName.c_str()); - AppFaultDataBySA faultDataSA; if (info.eventName == AppFreezeType::LIFECYCLE_TIMEOUT) { std::ifstream statmStream("/proc/" + std::to_string(info.pid) + "/statm"); @@ -299,6 +333,7 @@ int AppfreezeManager::LifecycleTimeoutHandle(const ParamInfo& info, FreezeUtil:: faultDataSA.token = flow.token; faultDataSA.state = static_cast(flow.state); } + faultDataSA.detectTime = AbilityRuntime::TimeUtil::CurrentTimeMillis(); DelayedSingleton::GetInstance()->NotifyAppFaultBySA(faultDataSA); return 0; } @@ -647,7 +682,7 @@ void AppfreezeManager::FindStackByPid(std::string& msg, int pid) const } } -std::string AppfreezeManager::CatchJsonStacktrace(int pid, const std::string& faultType, +std::pair AppfreezeManager::CatchJsonStacktrace(int pid, const std::string& faultType, const std::string& stack) const { HITRACE_METER_FMT(HITRACE_TAG_APP, "CatchJsonStacktrace pid:%{public}d", pid); @@ -673,7 +708,7 @@ std::string AppfreezeManager::CatchJsonStacktrace(int pid, const std::string& fa catchStackMap_[pid] = msg; } } - return msg; + return std::make_pair(msg, dumpResult.second); } std::string AppfreezeManager::CatcherStacktrace(int pid, const std::string& stack) const @@ -860,6 +895,62 @@ bool AppfreezeManager::IsValidFreezeFilter(int32_t pid, const std::string& bundl "pid:%{public}d", ret, bundleName.c_str(), pid); return ret; } + +void AppfreezeManager::ReportAppFreezeSysEvents(int32_t pid, const std::string& bundleName) +{ + if (freezeEventMap_.find(pid) == freezeEventMap_.end()) { + return; + } + + uint64_t now = AbilityRuntime::TimeUtil::CurrentTimeMillis(); + int ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::RELIABILITY, "APP_FREEZE_BEHAVIOR", + OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, + "THREAD_HALF_SCHED", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[0]].schedTime, + "THREAD_HALF_DETECT", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[0]].detectTime, + "THREAD_HALF_DUMP_START", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[0]].dumpStartTime, + "THREAD_HALF_DUMP_FINISH", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[0]].dumpFinishTime, + "THREAD_HALF_DUMP_RESULT", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[0]].dumpResult, + "THREAD_HALF_APP_STATUS", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[0]].appStatus, + "THREAD_TIMEOUT_SCHED", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[1]].schedTime, + "THREAD_TIMEOUT_DETECT", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[1]].detectTime, + "THREAD_TIMEOUT_DUMP_START", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[1]].dumpStartTime, + "THREAD_TIMEOUT_DUMP_FINISH", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[1]].dumpFinishTime, + "THREAD_TIMEOUT_DUMP_RESULT", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[1]].dumpResult, + "THREAD_TIMEOUT_APP_STATUS", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[1]].appStatus, + "INPUT_SCHED", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[2]].schedTime, + "INPUT_DETECT", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[2]].detectTime, + "INPUT_DUMP_START", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[2]].dumpStartTime, + "INPUT_DUMP_FINISH", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[2]].dumpFinishTime, + "INPUT_DUMP_RESULT", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[2]].dumpResult, + "INPUT_APP_STATUS", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[2]].appStatus, + "LIFECYCLE_HALF_SCHED", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[3]].schedTime, + "LIFECYCLE_HALF_DETECT", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[3]].detectTime, + "LIFECYCLE_HALF_DUMP_START", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[3]].dumpStartTime, + "LIFECYCLE_HALF_DUMP_FINISH", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[3]].dumpFinishTime, + "LIFECYCLE_HALF_DUMP_RESULT", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[3]].dumpResult, + "LIFECYCLE_HALF_APP_STATUS", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[3]].appStatus, + "LIFECYCLE_TIMEOUT_SCHED", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[4]].schedTime, + "LIFECYCLE_TIMEOUT_DETECT", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[4]].detectTime, + "LIFECYCLE_TIMEOUT_DUMP_START", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[4]].dumpStartTime, + "LIFECYCLE_TIMEOUT_DUMP_FINISH", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[4]].dumpFinishTime, + "LIFECYCLE_TIMEOUT_DUMP_RESULT", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[4]].dumpResult, + "LIFECYCLE_TIMEOUT_APP_STATUS", freezeEventMap_[pid][APP_FREEZE_EVENT_NAME[4]].appStatus, + "APP_KILL_TIME", freezeEventMap_[pid][KILL_EVENT_NAME].schedTime, + "APP_TERMINATED_TIME", now, + "SAMPLER_START", freezeEventMap_[pid][KILL_EVENT_NAME].dumpStartTime, + "SAMPLER_FINISH", freezeEventMap_[pid][KILL_EVENT_NAME].dumpFinishTime, + "SAMPLER_COUNT", freezeEventMap_[pid][KILL_EVENT_NAME].dumpResult); + freezeEventMap_.erase(pid); +} + +void AppfreezeManager::RegisterAppKillTime(int32_t pid, uint64_t time) +{ + if (freezeEventMap_.find(pid) == freezeEventMap_.end()) { + return; + } + freezeEventMap_[pid][KILL_EVENT_NAME].schedTime = time; +} + void AppfreezeManager::PerfStart(std::string eventName) { if (OHOS::system::GetParameter("const.dfx.sub_health_recovery.enable", "") != "true") { diff --git a/services/appdfr/src/application_anr_listener.cpp b/services/appdfr/src/application_anr_listener.cpp index 2a227ac69e64ac21e13015ced1617fb888105f02..026190aea22488d9eee60525c249ddbba6f860b8 100644 --- a/services/appdfr/src/application_anr_listener.cpp +++ b/services/appdfr/src/application_anr_listener.cpp @@ -68,6 +68,8 @@ void ApplicationAnrListener::OnAnr(int32_t pid, int32_t eventId) const faultData.notifyApp = false; faultData.forceExit = false; faultData.eventId = eventId; + faultData.schedTime = 0; + faultData.detectTime = AbilityRuntime::TimeUtil::CurrentTimeMillis(); DelayedSingleton::GetInstance()->NotifyAppFaultBySA(faultData); } } // namespace AAFwk diff --git a/services/appmgr/src/app_mgr_service_inner.cpp b/services/appmgr/src/app_mgr_service_inner.cpp index bf01910e4246a5785fcceeb6679c7cd671b8c14d..4f63f8d3c6482b593d450186b502944d62ff60ee 100644 --- a/services/appmgr/src/app_mgr_service_inner.cpp +++ b/services/appmgr/src/app_mgr_service_inner.cpp @@ -4825,6 +4825,8 @@ void AppMgrServiceInner::OnRemoteDied(const wptr &remote, bool is TAG_LOGI(AAFwkTag::APPMGR, "null appRecord"); return; } + AppExecFwk::AppfreezeManager::GetInstance()->ReportAppFreezeSysEvents(appRecord->GetPid(), + appRecord->GetBundleName()); AppExecFwk::AppfreezeManager::GetInstance()->RemoveDeathProcess(appRecord->GetBundleName()); std::vector> abilityTokens; for (const auto &token : appRecord->GetAbilities()) { @@ -7279,6 +7281,7 @@ int32_t AppMgrServiceInner::SubmitDfxFaultTask(const FaultData &faultData, const }; AppExecFwk::AppfreezeManager::GetInstance()->InitWarningCpuInfo(faultData, info); dfxTaskHandler_->SubmitTask(notifyAppTask, "NotifyAppFaultTask"); + dfxTaskHandler_->SubmitTask(notifyAppTask, "NotifyAppFaultTask"); TAG_LOGW(AAFwkTag::APPDFR, "submit NotifyAppFaultTask, eventName:%{public}s, bundleName:%{public}s, " "endTime:%{public}s, interval:%{public}" PRId64 " ms", faultData.errorObject.name.c_str(), bundleName.c_str(), AbilityRuntime::TimeUtil::DefaultCurrentTimeStr().c_str(), @@ -7384,20 +7387,24 @@ bool AppMgrServiceInner::CheckAppFault(const std::shared_ptr & int32_t AppMgrServiceInner::KillFaultApp(int32_t pid, const std::string &bundleName, const FaultData &faultData, bool isNeedExit) { - auto killAppTask = [pid, bundleName, faultData, isNeedExit, innerServiceWeak = weak_from_this()]() { - auto innerService = innerServiceWeak.lock(); - CHECK_POINTER_AND_RETURN_LOG(innerService, "get appMgrServiceInner fail"); - if (isNeedExit || (faultData.forceExit && !faultData.waitSaveState)) { + if (isNeedExit || (faultData.forceExit && !faultData.waitSaveState)) { + auto killAppTask = [pid, bundleName, faultData, isNeedExit, innerServiceWeak = weak_from_this()]() { + auto innerService = innerServiceWeak.lock(); + CHECK_POINTER_AND_RETURN_LOG(innerService, "get appMgrServiceInner fail"); TAG_LOGW(AAFwkTag::APPMGR, "faultData: %{public}s,pid: %{public}d will exit because %{public}s", bundleName.c_str(), pid, innerService->FaultTypeToString(faultData.faultType).c_str()); + uint64_t now = std::chrono::duration_cast( + std::chrono::steady_clock::now().time_since_epoch()).count(); + AppExecFwk::AppfreezeManager::GetInstance()->RegisterAppKillTime(now, pid); innerService->KillProcessByPid(pid, faultData.errorObject.name); return; - } - }; - constexpr int32_t waitTime = 3500; - // wait 3.5s before kill application - CHECK_POINTER_AND_RETURN_VALUE(taskHandler_, ERR_NO_INIT); - taskHandler_->SubmitTaskJust(killAppTask, "killAppTask", waitTime); + }; + constexpr int32_t waitTime = 3500; + // wait 3.5s before kill application + CHECK_POINTER_AND_RETURN_VALUE(taskHandler_, ERR_NO_INIT); + taskHandler_->SubmitTaskJust(killAppTask, "killAppTask", waitTime); + } + return ERR_OK; } @@ -7539,6 +7546,9 @@ FaultData AppMgrServiceInner::ConvertDataTypes(const AppFaultDataBySA &faultData newfaultData.token = faultData.token; newfaultData.state = faultData.state; newfaultData.eventId = faultData.eventId; + newfaultData.pid = faultData.pid; + newfaultData.schedTime = faultData.schedTime; + newfaultData.detectTime = faultData.detectTime; newfaultData.needKillProcess = faultData.needKillProcess; newfaultData.appfreezeInfo = faultData.appfreezeInfo; newfaultData.procStatm = faultData.procStatm; diff --git a/test/unittest/fault_data/fault_data_test.cpp b/test/unittest/fault_data/fault_data_test.cpp index 744c7ed81215ee0b414db5368079756ca569b0d0..1a62d9e05f40190dfd7ca263408309ba94f7dbeb 100644 --- a/test/unittest/fault_data/fault_data_test.cpp +++ b/test/unittest/fault_data/fault_data_test.cpp @@ -106,6 +106,13 @@ HWTEST_F(FaultDataTest, FaultDataTest_ReadFromParcel_002, TestSize.Level1) messageSixth.WriteBool(true); messageSixth.WriteUint32(12); messageSixth.WriteInt32(12); + messageSixth.WriteUint64(12); + messageSixth.WriteUint64(12); + messageSixth.WriteInt32(12); + messageSixth.WriteUint64(12); + messageSixth.WriteUint64(12); + messageSixth.WriteUint32(12); + messageSixth.WriteInt32(12); messageSixth.WriteInt32(12); messageSixth.WriteUint32(12); messageSixth.WriteBool(true); @@ -142,6 +149,13 @@ HWTEST_F(FaultDataTest, Unmarshalling_001, TestSize.Level1) message.WriteBool(true); message.WriteUint32(12); message.WriteInt32(12); + message.WriteUint32(12); + message.WriteInt32(12); + message.WriteUint64(12); + message.WriteUint64(12); + message.WriteInt32(12); + message.WriteUint64(12); + message.WriteUint64(12); message.WriteInt32(12); message.WriteUint32(12); message.WriteBool(true); @@ -233,6 +247,9 @@ HWTEST_F(FaultDataTest, ReadFromParcel_003, TestSize.Level1) messageSixth.WriteBool(true); messageSixth.WriteUint32(12); messageSixth.WriteInt32(12); + messageSixth.WriteUint64(12); + messageSixth.WriteUint64(12); + messageSixth.WriteInt32(12); messageSixth.WriteBool(true); messageSixth.WriteString(helloWord); messageSixth.WriteString(helloWord); @@ -268,6 +285,9 @@ HWTEST_F(FaultDataTest, Unmarshalling_002, TestSize.Level1) message.WriteBool(true); message.WriteUint32(12); message.WriteInt32(12); + message.WriteUint64(12); + message.WriteUint64(12); + message.WriteInt32(12); message.WriteBool(true); message.WriteString(helloWord); message.WriteString(helloWord);