!5953 appfreeze在AMS归一

Merge pull request !5953 from mgceshuang/master
This commit is contained in:
openharmony_ci
2023-07-18 13:42:35 +00:00
committed by Gitee
30 changed files with 1156 additions and 243 deletions
+1
View File
@@ -107,6 +107,7 @@ ohos_shared_library("appkit_native") {
"${ability_runtime_native_path}/appkit/app/ability_manager.cpp",
"${ability_runtime_native_path}/appkit/app/ability_record_mgr.cpp",
"${ability_runtime_native_path}/appkit/app/app_loader.cpp",
"${ability_runtime_native_path}/appkit/app/appfreeze_inner.cpp",
"${ability_runtime_native_path}/appkit/app/application_data_manager.cpp",
"${ability_runtime_native_path}/appkit/app/application_env.cpp",
"${ability_runtime_native_path}/appkit/app/application_env_impl.cpp",
@@ -0,0 +1,239 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "appfreeze_inner.h"
#include <sys/time.h>
#include "ability_manager_client.h"
#include "ability_state.h"
#include "app_recovery.h"
#include "hilog_wrapper.h"
#include "hisysevent.h"
#include "mix_stack_dumper.h"
#include "parameter.h"
#include "xcollie/watchdog.h"
namespace OHOS {
namespace AppExecFwk {
namespace {
constexpr char EVENT_UID[] = "UID";
constexpr char EVENT_PID[] = "PID";
constexpr char EVENT_MESSAGE[] = "MSG";
constexpr char EVENT_PACKAGE_NAME[] = "PACKAGE_NAME";
constexpr char EVENT_PROCESS_NAME[] = "PROCESS_NAME";
constexpr char EVENT_STACK[] = "STACK";
}
std::weak_ptr<EventHandler> AppfreezeInner::appMainHandler_;
std::shared_ptr<AppfreezeInner> AppfreezeInner::instance_ = nullptr;
std::mutex AppfreezeInner::singletonMutex_;
AppfreezeInner::AppfreezeInner()
{}
AppfreezeInner::~AppfreezeInner()
{}
void AppfreezeInner::SetMainHandler(const std::shared_ptr<EventHandler>& eventHandler)
{
appMainHandler_ = eventHandler;
}
void AppfreezeInner::SetApplicationInfo(const std::shared_ptr<ApplicationInfo>& applicationInfo)
{
applicationInfo_ = applicationInfo;
}
std::shared_ptr<AppfreezeInner> AppfreezeInner::GetInstance()
{
if (instance_ == nullptr) {
std::lock_guard<std::mutex> lock(singletonMutex_);
if (instance_ == nullptr) {
instance_ = std::make_shared<AppfreezeInner>();
}
}
return instance_;
}
void AppfreezeInner::DestroyInstance()
{
std::lock_guard<std::mutex> lock(singletonMutex_);
if (instance_ != nullptr) {
instance_.reset();
instance_ = nullptr;
}
}
bool AppfreezeInner::IsHandleAppfreeze()
{
auto applicationInfo = applicationInfo_.lock();
if (applicationInfo == nullptr) {
HILOG_ERROR("applicationInfo_ is nullptr.");
return false;
}
const int buffSize = 128;
char paramOutBuff[buffSize] = {0};
GetParameter("hiviewdfx.appfreeze.filter_bundle_name", "", paramOutBuff, buffSize - 1);
std::string str(paramOutBuff);
std::string& bundleName = applicationInfo->bundleName;
if (bundleName.empty()) {
return true;
}
if (str.find(bundleName) != std::string::npos) {
HILOG_WARN("appfreeze filtration %{public}s.", bundleName.c_str());
return false;
}
return true;
}
int AppfreezeInner::AppfreezeHandle(const FaultData& faultData, bool onlyMainThread)
{
if (!IsHandleAppfreeze()) {
NotifyANR(faultData);
return -1;
}
auto reportFreeze = [faultData, onlyMainThread]() {
if (faultData.errorObject.name == "") {
HILOG_ERROR("name is nullptr, AppfreezeHandle failed.");
return;
}
AppExecFwk::AppfreezeInner::GetInstance()->AcquireStack(faultData, onlyMainThread);
};
OHOS::HiviewDFX::Watchdog::GetInstance().RunOneShotTask("reportAppFreeze", reportFreeze);
return 0;
}
bool AppfreezeInner::IsExitApp(const std::string& name)
{
if (name == AppFreezeType::THREAD_BLOCK_6S) {
return true;
}
if (name == AppFreezeType::APP_INPUT_BLOCK) {
return true;
}
return false;
}
int AppfreezeInner::AcquireStack(const FaultData& faultInfo, bool onlyMainThread)
{
HILOG_DEBUG("Start dump mixstack.");
std::string stack = MixStackDumper::GetMixStack(onlyMainThread);
HILOG_DEBUG("Start dump MainHandler message.");
std::string msgContent = faultInfo.errorObject.message + "\n";
auto mainHandler = appMainHandler_.lock();
if (mainHandler == nullptr) {
msgContent += "mainHandler is destructed!";
} else {
MainHandlerDumper handlerDumper;
msgContent += "mainHandler dump is:\n";
mainHandler->Dump(handlerDumper);
msgContent += handlerDumper.GetDumpInfo();
}
HILOG_DEBUG("end dump message is %{public}s", msgContent.c_str());
FaultData faultData;
faultData.errorObject.message = msgContent;
faultData.errorObject.stack = stack;
faultData.errorObject.name = faultInfo.errorObject.name;
faultData.faultType = FaultDataType::APP_FREEZE;
faultData.timeoutMarkers = faultInfo.timeoutMarkers;
faultData.notifyApp = false;
faultData.waitSaveState = false;
faultData.forceExit = false;
bool isExit = IsExitApp(faultInfo.errorObject.name);
if (isExit) {
faultData.forceExit = true;
faultData.waitSaveState = AppRecovery::GetInstance().IsEnabled();
}
int ret = NotifyANR(faultData);
if (isExit) {
AppFreezeRecovery();
}
HILOG_DEBUG("End notify appfreeze");
return ret;
}
void AppfreezeInner::ThreadBlock(std::atomic_bool& isSixSecondEvent)
{
FaultData faultData;
faultData.errorObject.message = "App main thread is not response!";
faultData.faultType = FaultDataType::APP_FREEZE;
faultData.timeoutMarkers = "";
bool onlyMainThread = false;
if (isSixSecondEvent) {
faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_6S;
onlyMainThread = true;
} else {
faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_3S;
isSixSecondEvent.store(true);
}
AppfreezeHandle(faultData, onlyMainThread);
}
int AppfreezeInner::NotifyANR(const FaultData& faultData)
{
auto applicationInfo = applicationInfo_.lock();
if (applicationInfo == nullptr) {
HILOG_ERROR("reportEvent fail, applicationInfo_ is nullptr.");
return -1;
}
int32_t pid = static_cast<int32_t>(getpid());
HILOG_INFO("reportEvent:%{public}s, pid:%{public}d, bundleName:%{public}s. success",
faultData.errorObject.name.c_str(), pid, applicationInfo->bundleName.c_str());
// move this call before force stop app ? such as merge to NotifyAppFault ?
DelayedSingleton<AbilityManagerClient>::GetInstance()->RecordAppExitReason(REASON_APP_FREEZE);
int ret = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->NotifyAppFault(faultData);
if (ret != 0) {
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, faultData.errorObject.name,
OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_UID, applicationInfo->uid,
EVENT_PID, pid, EVENT_PACKAGE_NAME, applicationInfo->bundleName,
EVENT_PROCESS_NAME, applicationInfo->process, EVENT_MESSAGE,
faultData.errorObject.message, EVENT_STACK, faultData.errorObject.stack);
}
return ret;
}
void AppfreezeInner::AppFreezeRecovery()
{
AppRecovery::GetInstance().ScheduleSaveAppState(StateReason::APP_FREEZE);
AppRecovery::GetInstance().ScheduleRecoverApp(StateReason::APP_FREEZE);
}
void MainHandlerDumper::Dump(const std::string &message)
{
dumpInfo += message;
}
std::string MainHandlerDumper::GetTag()
{
return "";
}
std::string MainHandlerDumper::GetDumpInfo()
{
return dumpInfo;
}
} // namespace AAFwk
} // namespace OHOS
+16 -10
View File
@@ -29,6 +29,7 @@
#include "ability_util.h"
#include "app_loader.h"
#include "app_recovery.h"
#include "appfreeze_inner.h"
#include "application_data_manager.h"
#include "application_env_impl.h"
#include "bundle_mgr_proxy.h"
@@ -893,10 +894,7 @@ bool MainThread::InitCreate(
HILOG_ERROR("MainThread::InitCreate create contextDeal failed");
return false;
}
if (watchdog_ != nullptr) {
watchdog_->SetApplicationInfo(applicationInfo_);
}
AppExecFwk::AppfreezeInner::GetInstance()->SetApplicationInfo(applicationInfo_);
application_->SetProcessInfo(processInfo_);
contextDeal->SetApplicationInfo(applicationInfo_);
@@ -2032,6 +2030,7 @@ void MainThread::Init(const std::shared_ptr<EventRunner> &runner)
TaskTimeoutDetected(runner);
watchdog_->Init(mainHandler_);
AppExecFwk::AppfreezeInner::GetInstance()->SetMainHandler(mainHandler_);
extensionConfigMgr_->Init();
}
@@ -2511,6 +2510,11 @@ int32_t MainThread::ScheduleNotifyAppFault(const FaultData &faultData)
HILOG_ERROR("mainHandler is nullptr");
return ERR_INVALID_VALUE;
}
if (faultData.faultType == FaultDataType::APP_FREEZE) {
return AppExecFwk::AppfreezeInner::GetInstance()->AppfreezeHandle(faultData, false);
}
wptr<MainThread> weak = this;
auto task = [weak, faultData] {
auto appThread = weak.promote();
@@ -2526,12 +2530,14 @@ int32_t MainThread::ScheduleNotifyAppFault(const FaultData &faultData)
void MainThread::NotifyAppFault(const FaultData &faultData)
{
ErrorObject faultErrorObj = {
.name = faultData.errorObject.name,
.message = faultData.errorObject.message,
.stack = faultData.errorObject.stack
};
ApplicationDataManager::GetInstance().NotifyExceptionObject(faultErrorObj);
if (faultData.notifyApp) {
ErrorObject faultErrorObj = {
.name = faultData.errorObject.name,
.message = faultData.errorObject.message,
.stack = faultData.errorObject.stack
};
ApplicationDataManager::GetInstance().NotifyExceptionObject(faultErrorObj);
}
}
void MainThread::SetProcessExtensionType(const std::shared_ptr<AbilityLocalRecord> &abilityRecord)
+2 -63
View File
@@ -20,6 +20,7 @@
#include "app_mgr_client.h"
#include "app_recovery.h"
#include "appfreeze_inner.h"
#include "hisysevent.h"
#include "hilog_wrapper.h"
#include "mix_stack_dumper.h"
@@ -28,12 +29,6 @@
namespace OHOS {
namespace AppExecFwk {
namespace {
constexpr char EVENT_KEY_UID[] = "UID";
constexpr char EVENT_KEY_PID[] = "PID";
constexpr char EVENT_KEY_MESSAGE[] = "MSG";
constexpr char EVENT_KEY_PACKAGE_NAME[] = "PACKAGE_NAME";
constexpr char EVENT_KEY_PROCESS_NAME[] = "PROCESS_NAME";
constexpr char EVENT_KEY_STACK[] = "STACK";
constexpr uint32_t CHECK_MAIN_THREAD_IS_ALIVE = 1;
constexpr int RESET_RATIO = 2;
@@ -87,11 +82,6 @@ void Watchdog::Stop()
}
}
void Watchdog::SetApplicationInfo(const std::shared_ptr<ApplicationInfo> &applicationInfo)
{
applicationInfo_ = applicationInfo;
}
void Watchdog::SetAppMainThreadState(const bool appMainThreadState)
{
appMainThreadIsAlive_.store(appMainThreadState);
@@ -170,65 +160,14 @@ void Watchdog::ReportEvent()
return;
}
if (applicationInfo_ == nullptr) {
HILOG_ERROR("reportEvent fail, applicationInfo_ is nullptr.");
return;
}
if (!needReport_) {
return;
}
std::string eventType;
std::string stack = "";
if (isSixSecondEvent_) {
eventType = "THREAD_BLOCK_6S";
needReport_.store(false);
stack = MixStackDumper::GetMixStack(true);
} else {
eventType = "THREAD_BLOCK_3S";
isSixSecondEvent_.store(true);
stack = MixStackDumper::GetMixStack(false);
}
HILOG_DEBUG("Start dump message.");
std::string msgContent = "App main thread is not response!";
MainHandlerDumper handlerDumper;
appMainHandler_->Dump(handlerDumper);
msgContent += handlerDumper.GetDumpInfo();
HILOG_DEBUG("msgContent is %{public}s", msgContent.c_str());
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, eventType,
OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_KEY_UID, applicationInfo_->uid,
EVENT_KEY_PID, static_cast<int32_t>(getpid()), EVENT_KEY_PACKAGE_NAME, applicationInfo_->bundleName,
EVENT_KEY_PROCESS_NAME, applicationInfo_->process, EVENT_KEY_MESSAGE, msgContent, EVENT_KEY_STACK, stack);
HILOG_INFO("reportEvent success");
HILOG_DEBUG("reportEvent info, %{public}zu %{public}s", msgContent.size(), msgContent.c_str());
// should call error manager-> appRecovery
if (eventType == "THREAD_BLOCK_6S") {
AppRecovery::GetInstance().ScheduleSaveAppState(StateReason::APP_FREEZE);
AppRecovery::GetInstance().ScheduleRecoverApp(StateReason::APP_FREEZE);
FaultData faultData;
faultData.faultType = FaultDataType::APP_FREEZE;
faultData.errorObject.message = msgContent;
faultData.errorObject.stack = stack;
faultData.errorObject.name = eventType;
DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->NotifyAppFault(faultData);
}
}
void MainHandlerDumper::Dump(const std::string &message)
{
dumpInfo += message;
}
std::string MainHandlerDumper::GetTag()
{
return "";
}
std::string MainHandlerDumper::GetDumpInfo()
{
return dumpInfo;
AppExecFwk::AppfreezeInner::GetInstance()->ThreadBlock(isSixSecondEvent_);
}
} // namespace AppExecFwk
} // namespace OHOS
+18
View File
@@ -20,6 +20,16 @@ LIFECYCLE_TIMEOUT:
PACKAGE_NAME: {type: STRING, desc: package name}
PROCESS_NAME: {type: STRING, desc: process name}
MSG: {type: STRING, desc: application event message}
STACK: {type: STRING, desc: main thread stacktrace}
LIFECYCLE_HALF_TIMEOUT:
__BASE: {type: FAULT, level: CRITICAL, tag: STABILITY, desc: ability timeout}
PID: {type: INT32, desc: process id}
UID: {type: INT32, desc: app uid}
PACKAGE_NAME: {type: STRING, desc: package name}
PROCESS_NAME: {type: STRING, desc: process name}
MSG: {type: STRING, desc: application event message}
STACK: {type: STRING, desc: main thread stacktrace}
APP_LIFECYCLE_TIMEOUT:
__BASE: {type: FAULT, level: CRITICAL, tag: STABILITY, desc: application timeout}
@@ -57,6 +67,14 @@ THREAD_BLOCK_6S:
MSG: {type: STRING, desc: application event message}
STACK: {type: STRING, desc: main thread stacktrace}
APP_INPUT_BLOCK:
__BASE: {type: FAULT, level: CRITICAL, tag: STABILITY, desc: application freeze}
PID: {type: INT32, desc: process id}
UID: {type: INT32, desc: app uid}
PACKAGE_NAME: {type: STRING, desc: package name}
PROCESS_NAME: {type: STRING, desc: process name}
MSG: {type: STRING, desc: application event message}
STACK: {type: STRING, desc: main thread stacktrace}
# fault event
START_ABILITY_ERROR:
@@ -68,6 +68,7 @@ ohos_shared_library("app_manager") {
"src/appmgr/app_state_callback_proxy.cpp",
"src/appmgr/app_state_data.cpp",
"src/appmgr/app_task_info.cpp",
"src/appmgr/appfreeze_manager.cpp",
"src/appmgr/application_state_observer_proxy.cpp",
"src/appmgr/application_state_observer_stub.cpp",
"src/appmgr/component_interception_proxy.cpp",
@@ -107,8 +108,13 @@ ohos_shared_library("app_manager") {
"ability_base:want",
"bundle_framework:appexecfwk_base",
"c_utils:utils",
"faultloggerd:libdfx_dumpcatcher",
"faultloggerd:libfaultloggerd",
"ffrt:libffrt",
"hilog:libhilog",
"hisysevent:libhisysevent",
"hitrace:hitrace_meter",
"init:libbegetutil",
"ipc:ipc_core",
"samgr:samgr_proxy",
]
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_ABILITY_RUNTIME_APPFREEZE_MAMAGER_H
#define OHOS_ABILITY_RUNTIME_APPFREEZE_MAMAGER_H
#include <sys/types.h>
#include <fstream>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "cpp/mutex.h"
#include "cpp/condition_variable.h"
#include "fault_data.h"
namespace OHOS {
namespace AppExecFwk {
class AppfreezeManager : public std::enable_shared_from_this<AppfreezeManager> {
public:
struct AppInfo {
int pid;
int uid;
std::string bundleName;
std::string processName;
};
enum TypeAttribute {
NORMAL_TIMEOUT = 0,
CRITICAL_TIMEOUT = 1,
};
AppfreezeManager();
~AppfreezeManager();
static std::shared_ptr<AppfreezeManager> GetInstance();
static void DestroyInstance();
int AppfreezeHandle(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo);
int AppfreezeHandleWithStack(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo);
int LifecycleTimeoutHandle(int typeId, int32_t pid, const std::string& eventName,
const std::string& bundleName, const std::string& msg);
bool IsHandleAppfreeze(const std::string& bundleName);
private:
AppfreezeManager& operator=(const AppfreezeManager&) = delete;
AppfreezeManager(const AppfreezeManager&) = delete;
uint64_t GetMilliseconds();
std::map<int, std::set<int>> BinderParser(std::ifstream& fin, std::string& stack) const;
void ParseBinderPids(const std::map<int, std::set<int>>& binderInfo, std::set<int>& pids, int pid) const;
std::set<int> GetBinderPeerPids(std::string& stack, int pid) const;
std::string CatcherStacktrace(int pid) const;
int AcquireStack(const FaultData& faultData, const AppInfo& appInfo);
int NotifyANR(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo);
static const inline std::string LOGGER_DEBUG_PROC_PATH = "/proc/transaction_proc";
ffrt::mutex lifecycleMutex_;
ffrt::condition_variable lifecycleCv_;
std::set<std::string> lifecycleTimeOutMarks_;
std::string name_;
static ffrt::mutex singletonMutex_;
static std::shared_ptr<AppfreezeManager> instance_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_APPFREEZE_MAMAGER_H
@@ -37,6 +37,15 @@ enum class FaultDataType {
RESOURCE_CONTROL
};
class AppFreezeType {
public:
static constexpr char LIFECYCLE_HALF_TIMEOUT[] = "LIFECYCLE_HALF_TIMEOUT";
static constexpr char LIFECYCLE_TIMEOUT[] = "LIFECYCLE_TIMEOUT";
static constexpr char APP_LIFECYCLE_TIMEOUT[] = "APP_LIFECYCLE_TIMEOUT";
static constexpr char THREAD_BLOCK_3S[] = "THREAD_BLOCK_3S";
static constexpr char THREAD_BLOCK_6S[] = "THREAD_BLOCK_6S";
static constexpr char APP_INPUT_BLOCK[] = "APP_INPUT_BLOCK";
};
/**
* @struct FaultData
* FaultData is used to save information about faultdata.
@@ -48,6 +57,10 @@ struct FaultData : public Parcelable {
// error object
ErrorObject errorObject;
FaultDataType faultType = FaultDataType::UNKNOWN;
std::string timeoutMarkers;
bool waitSaveState = false;
bool notifyApp = false;
bool forceExit = false;
};
/**
@@ -62,6 +75,10 @@ struct AppFaultDataBySA : public Parcelable {
ErrorObject errorObject;
FaultDataType faultType = FaultDataType::UNKNOWN;
int32_t pid = -1;
std::string timeoutMarkers;
bool waitSaveState = false;
bool notifyApp = false;
bool forceExit = false;
};
} // namespace AppExecFwk
} // namespace OHOS
@@ -577,7 +577,7 @@ int32_t AppSchedulerProxy::ScheduleNotifyAppFault(const FaultData &faultData)
}
MessageParcel reply;
MessageOption option;
MessageOption option(MessageOption::TF_ASYNC);
auto ret = remote->SendRequest(static_cast<uint32_t>(IAppScheduler::Message::SCHEDULE_NOTIFY_FAULT),
data, reply, option);
if (ret != NO_ERROR) {
@@ -0,0 +1,329 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "appfreeze_manager.h"
#include <fcntl.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include "faultloggerd_client.h"
#include "file_ex.h"
#include "dfx_dump_catcher.h"
#include "directory_ex.h"
#include "hisysevent.h"
#include "parameter.h"
#include "singleton.h"
#include "app_mgr_client.h"
#include "hilog_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
namespace {
constexpr char EVENT_UID[] = "UID";
constexpr char EVENT_PID[] = "PID";
constexpr char EVENT_MESSAGE[] = "MSG";
constexpr char EVENT_PACKAGE_NAME[] = "PACKAGE_NAME";
constexpr char EVENT_PROCESS_NAME[] = "PROCESS_NAME";
constexpr char EVENT_STACK[] = "STACK";
}
std::shared_ptr<AppfreezeManager> AppfreezeManager::instance_ = nullptr;
ffrt::mutex AppfreezeManager::singletonMutex_;
AppfreezeManager::AppfreezeManager()
{
name_ = "AppfreezeManager" + std::to_string(GetMilliseconds());
}
AppfreezeManager::~AppfreezeManager()
{
}
std::shared_ptr<AppfreezeManager> AppfreezeManager::GetInstance()
{
if (instance_ == nullptr) {
std::lock_guard<ffrt::mutex> lock(singletonMutex_);
if (instance_ == nullptr) {
instance_ = std::make_shared<AppfreezeManager>();
}
}
return instance_;
}
void AppfreezeManager::DestroyInstance()
{
std::lock_guard<ffrt::mutex> lock(singletonMutex_);
if (instance_ != nullptr) {
instance_.reset();
instance_ = nullptr;
}
}
uint64_t AppfreezeManager::GetMilliseconds()
{
auto now = std::chrono::system_clock::now();
auto millisecs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
return millisecs.count();
}
bool AppfreezeManager::IsHandleAppfreeze(const std::string& bundleName)
{
if (bundleName.empty()) {
return true;
}
const int buffSize = 128;
char paramOutBuff[buffSize] = {0};
GetParameter("hiviewdfx.appfreeze.filter_bundle_name", "", paramOutBuff, buffSize - 1);
std::string str(paramOutBuff);
if (str.find(bundleName) != std::string::npos) {
HILOG_WARN("appfreeze filtration %{public}s.", bundleName.c_str());
return false;
}
return true;
}
int AppfreezeManager::AppfreezeHandle(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo)
{
HILOG_DEBUG("called %{public}s, bundleName %{public}s, name_ %{public}s",
faultData.errorObject.name.c_str(), appInfo.bundleName.c_str(), name_.c_str());
if (!IsHandleAppfreeze(appInfo.bundleName)) {
return -1;
}
if (faultData.errorObject.name == AppFreezeType::APP_INPUT_BLOCK) {
AcquireStack(faultData, appInfo);
} else if (faultData.errorObject.name == AppFreezeType::LIFECYCLE_TIMEOUT ||
faultData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT) {
NotifyANR(faultData, appInfo);
{
std::unique_lock<ffrt::mutex> lock(lifecycleMutex_);
lifecycleTimeOutMarks_.erase(faultData.timeoutMarkers);
}
lifecycleCv_.notify_all();
} else {
NotifyANR(faultData, appInfo);
}
return 0;
}
int AppfreezeManager::AppfreezeHandleWithStack(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo)
{
HILOG_DEBUG("called %{public}s, bundleName %{public}s, name_ %{public}s",
faultData.errorObject.name.c_str(), appInfo.bundleName.c_str(), name_.c_str());
if (!IsHandleAppfreeze(appInfo.bundleName)) {
return -1;
}
FaultData faultNotifyData;
faultNotifyData.errorObject.name = faultData.errorObject.name;
faultNotifyData.errorObject.message = faultData.errorObject.message;
faultNotifyData.errorObject.stack = faultData.errorObject.stack + "\n";
faultNotifyData.faultType = FaultDataType::APP_FREEZE;
faultNotifyData.errorObject.stack += CatcherStacktrace(appInfo.pid);
return AppfreezeHandle(faultNotifyData, appInfo);
}
int AppfreezeManager::LifecycleTimeoutHandle(int typeId, int32_t pid,
const std::string& eventName, const std::string& bundleName, const std::string& msg)
{
if (typeId != AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT) {
return -1;
}
if (!IsHandleAppfreeze(bundleName)) {
return -1;
}
if (eventName != AppFreezeType::LIFECYCLE_TIMEOUT &&
eventName != AppFreezeType::LIFECYCLE_HALF_TIMEOUT) {
return -1;
}
HILOG_DEBUG("LifecycleTimeoutHandle called %{public}s, name_ %{public}s",
bundleName.c_str(), name_.c_str());
AppFaultDataBySA faultDataSA;
faultDataSA.errorObject.name = eventName;
faultDataSA.errorObject.message = msg;
faultDataSA.faultType = FaultDataType::APP_FREEZE;
faultDataSA.timeoutMarkers = "notifyFault" +
std::to_string(pid) +
"-" + std::to_string(GetMilliseconds());
faultDataSA.pid = pid;
DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->NotifyAppFaultBySA(faultDataSA);
auto lcTimeout = 3500; // ms
std::chrono::milliseconds timeout { lcTimeout };
std::unique_lock<ffrt::mutex> lock(lifecycleMutex_);
lifecycleTimeOutMarks_.insert(faultDataSA.timeoutMarkers);
auto ret = lifecycleCv_.wait_for(lock, timeout,
[t = shared_from_this(), marker = faultDataSA.timeoutMarkers] {
return t->lifecycleTimeOutMarks_.find(marker) == t->lifecycleTimeOutMarks_.end();
});
if (!ret) {
lifecycleTimeOutMarks_.erase(faultDataSA.timeoutMarkers);
HILOG_WARN("LifecycleTimeoutHandle timeout, name_ %{public}s", name_.c_str());
return -1;
}
return 0;
}
int AppfreezeManager::AcquireStack(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo)
{
int ret = 0;
int pid = appInfo.pid;
FaultData faultNotifyData;
faultNotifyData.errorObject.name = faultData.errorObject.name;
faultNotifyData.errorObject.message = faultData.errorObject.message;
faultNotifyData.errorObject.stack = faultData.errorObject.stack + "\n";
faultNotifyData.faultType = FaultDataType::APP_FREEZE;
std::string& stack = faultNotifyData.errorObject.stack;
std::set<int> pids = GetBinderPeerPids(faultNotifyData.errorObject.stack, pid);
if (pids.empty()) {
stack += "PeerBinder pids is empty\n";
}
for (auto& pidTemp : pids) {
HILOG_INFO("pidTemp pids:%{public}d", pidTemp);
if (pidTemp != pid) {
std::string content = "PeerBinder catcher stacktrace for pid : " + std::to_string(pidTemp) + "\n";
content += CatcherStacktrace(pidTemp);
stack += content;
}
}
ret = NotifyANR(faultNotifyData, appInfo);
return ret;
}
int AppfreezeManager::NotifyANR(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo)
{
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, faultData.errorObject.name,
OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_UID, appInfo.uid,
EVENT_PID, appInfo.pid, EVENT_PACKAGE_NAME, appInfo.bundleName,
EVENT_PROCESS_NAME, appInfo.processName, EVENT_MESSAGE,
faultData.errorObject.message, EVENT_STACK, faultData.errorObject.stack);
HILOG_INFO("reportEvent:%{public}s, pid:%{public}d, bundleName:%{public}s. success",
faultData.errorObject.name.c_str(), appInfo.pid, appInfo.bundleName.c_str());
return 0;
}
std::map<int, std::set<int>> AppfreezeManager::BinderParser(std::ifstream& fin, std::string& stack) const
{
std::map<int, std::set<int>> binderInfo;
const int decimal = 10;
std::string line;
bool isBinderMatchup = false;
stack += "BinderCatcher --\n\n";
while (getline(fin, line)) {
stack += line + "\n";
if (isBinderMatchup) {
continue;
}
if (line.find("async") != std::string::npos) {
continue;
}
std::istringstream lineStream(line);
std::vector<std::string> strList;
std::string tmpstr;
while (lineStream >> tmpstr) {
strList.push_back(tmpstr);
}
auto SplitPhase = [](const std::string& str, uint16_t index) -> std::string {
std::vector<std::string> strings;
SplitStr(str, ":", strings);
if (index < strings.size()) {
return strings[index];
}
return "";
};
if (strList.size() == 7) { // 7: valid array size
// 2: peer id,
std::string server = SplitPhase(strList[2], 0);
// 0: local id,
std::string client = SplitPhase(strList[0], 0);
// 5: wait time, s
std::string wait = SplitPhase(strList[5], 1);
if (server == "" || client == "" || wait == "") {
continue;
}
int serverNum = std::strtol(server.c_str(), nullptr, decimal);
int clientNum = std::strtol(client.c_str(), nullptr, decimal);
int waitNum = std::strtol(wait.c_str(), nullptr, decimal);
HILOG_INFO("server:%{public}d, client:%{public}d, wait:%{public}d", serverNum, clientNum, waitNum);
binderInfo[clientNum].insert(serverNum);
}
if (line.find("context") != line.npos) {
isBinderMatchup = true;
}
}
HILOG_INFO("binderInfo size: %{public}zu", binderInfo.size());
return binderInfo;
}
std::set<int> AppfreezeManager::GetBinderPeerPids(std::string& stack, int pid) const
{
std::set<int> pids;
std::ifstream fin;
std::string path = LOGGER_DEBUG_PROC_PATH;
fin.open(path.c_str());
if (!fin.is_open()) {
HILOG_ERROR("open file failed, %{public}s.", path.c_str());
stack += "open file failed :" + path + "\r\n";
return pids;
}
stack += "\n\nPeerBinderCatcher -- pid==" + std::to_string(pid) + "\n\n";
std::map<int, std::set<int>> binderInfo = BinderParser(fin, stack);
fin.close();
if (binderInfo.size() == 0 || binderInfo.find(pid) == binderInfo.end()) {
return pids;
}
ParseBinderPids(binderInfo, pids, pid);
for (auto& each : pids) {
HILOG_DEBUG("each pids:%{public}d", each);
}
return pids;
}
void AppfreezeManager::ParseBinderPids(const std::map<int, std::set<int>>& binderInfo,
std::set<int>& pids, int pid) const
{
auto it = binderInfo.find(pid);
if (it != binderInfo.end()) {
for (auto& each : it->second) {
pids.insert(each);
ParseBinderPids(binderInfo, pids, each);
}
}
}
std::string AppfreezeManager::CatcherStacktrace(int pid) const
{
HiviewDFX::DfxDumpCatcher dumplog;
std::string ret;
std::string msg;
if (!dumplog.DumpCatch(pid, 0, msg)) {
ret = "Failed to dump stacktrace for " + std::to_string(pid) + "\n" + msg;
} else {
ret = msg;
}
return ret;
}
} // namespace AAFwk
} // namespace OHOS
@@ -43,6 +43,15 @@ bool FaultData::ReadFromParcel(Parcel &parcel)
return false;
}
faultType = static_cast<FaultDataType>(type);
if (!parcel.ReadString(strValue)) {
return false;
}
timeoutMarkers = strValue;
waitSaveState = parcel.ReadBool();
notifyApp = parcel.ReadBool();
forceExit = parcel.ReadBool();
return true;
}
@@ -73,6 +82,22 @@ bool FaultData::Marshalling(Parcel &parcel) const
if (!parcel.WriteInt32(static_cast<int32_t>(faultType))) {
return false;
}
if (!parcel.WriteString(timeoutMarkers)) {
return false;
}
if (!parcel.WriteBool(waitSaveState)) {
return false;
}
if (!parcel.WriteBool(notifyApp)) {
return false;
}
if (!parcel.WriteBool(forceExit)) {
return false;
}
return true;
}
@@ -103,6 +128,15 @@ bool AppFaultDataBySA::ReadFromParcel(Parcel &parcel)
if (!parcel.ReadInt32(pid)) {
return false;
}
if (!parcel.ReadString(strValue)) {
return false;
}
timeoutMarkers = strValue;
waitSaveState = parcel.ReadBool();
notifyApp = parcel.ReadBool();
forceExit = parcel.ReadBool();
return true;
}
@@ -137,6 +171,22 @@ bool AppFaultDataBySA::Marshalling(Parcel &parcel) const
if (!parcel.WriteInt32(pid)) {
return false;
}
if (!parcel.WriteString(timeoutMarkers)) {
return false;
}
if (!parcel.WriteBool(waitSaveState)) {
return false;
}
if (!parcel.WriteBool(notifyApp)) {
return false;
}
if (!parcel.WriteBool(forceExit)) {
return false;
}
return true;
}
} // namespace AppExecFwk
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_ABILITY_ABILITY_APPFREEZE_LOG_CLIENT_H
#define OHOS_ABILITY_ABILITY_APPFREEZE_LOG_CLIENT_H
#include <map>
#include <memory>
#include <mutex>
#include <thread>
#include <set>
#include <sys/types.h>
#include "refbase.h"
#include "singleton.h"
#include "event_handler.h"
#include "app_mgr_client.h"
#include "app_mgr_interface.h"
#include "application_impl.h"
#include "fault_data.h"
namespace OHOS {
namespace AppExecFwk {
class AppfreezeInner {
public:
AppfreezeInner();
~AppfreezeInner();
static std::shared_ptr<AppfreezeInner> GetInstance();
static void DestroyInstance();
static void SetMainHandler(const std::shared_ptr<EventHandler>& eventHandler);
void SetApplicationInfo(const std::shared_ptr<ApplicationInfo>& applicationInfo);
void ThreadBlock(std::atomic_bool& isSixSecondEvent);
int AppfreezeHandle(const FaultData& faultInfo, bool onlyMainThread);
int AcquireStack(const FaultData& faultInfo, bool onlyMainThread);
private:
static std::weak_ptr<EventHandler> appMainHandler_;
std::weak_ptr<ApplicationInfo> applicationInfo_;
void AppFreezeRecovery();
int NotifyANR(const FaultData& faultData);
bool IsExitApp(const std::string& name);
bool IsHandleAppfreeze();
static std::mutex singletonMutex_;
static std::shared_ptr<AppfreezeInner> instance_;
};
class MainHandlerDumper : public Dumper {
public:
virtual void Dump(const std::string &message) override;
virtual std::string GetTag() override;
std::string GetDumpInfo();
private:
std::string dumpInfo;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_ABILITY_ABILITY_APPFREEZE_LOG_CLIENT_H
@@ -47,14 +47,6 @@ public:
*/
void Stop();
/**
*
* @brief Set the info of application.
*
* @param applicationInfo The info of application
*/
void SetApplicationInfo(const std::shared_ptr<ApplicationInfo> &applicationInfo);
/**
*
* @brief Set the state of main thread.
@@ -100,21 +92,11 @@ private:
std::atomic_bool needReport_ = true;
std::atomic_bool isSixSecondEvent_ = false;
std::atomic_bool isInBackground_ = true;
std::shared_ptr<ApplicationInfo> applicationInfo_ = nullptr;
std::mutex cvMutex_;
std::condition_variable cvWatchdog_;
static std::shared_ptr<EventHandler> appMainHandler_;
int64_t lastWatchTime_ = 0;
};
class MainHandlerDumper : public Dumper {
public:
virtual void Dump(const std::string &message) override;
virtual std::string GetTag() override;
std::string GetDumpInfo();
private:
std::string dumpInfo;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_WATCHDOG_H
@@ -41,10 +41,10 @@ public:
void ProcessEvent(const EventWrap &event) override;
private:
void ProcessLoadTimeOut(int64_t abilityRecordId);
void ProcessLoadTimeOut(const EventWrap &event);
void ProcessActiveTimeOut(int64_t abilityRecordId);
void ProcessInactiveTimeOut(int64_t abilityRecordId);
void ProcessForegroundTimeOut(int64_t abilityRecordId);
void ProcessForegroundTimeOut(const EventWrap &event);
void ProcessShareDataTimeOut(int64_t uniqueId);
private:
std::weak_ptr<AbilityManagerService> server_;
@@ -705,10 +705,10 @@ public:
void OnAbilityDied(std::shared_ptr<AbilityRecord> abilityRecord);
void OnCallConnectDied(std::shared_ptr<CallRecord> callRecord);
void HandleLoadTimeOut(int64_t abilityRecordId);
void HandleLoadTimeOut(int64_t abilityRecordId, bool isHalf = false);
void HandleActiveTimeOut(int64_t abilityRecordId);
void HandleInactiveTimeOut(int64_t abilityRecordId);
void HandleForegroundTimeOut(int64_t abilityRecordId);
void HandleForegroundTimeOut(int64_t abilityRecordId, bool isHalf = false);
void HandleShareDataTimeOut(int64_t uniqueId);
int32_t GetShareDataPairAndReturnData(std::shared_ptr<AbilityRecord> abilityRecord,
const int32_t &resultCode, const int32_t &uniqueId, WantParams &wantParam);
@@ -1404,6 +1404,8 @@ private:
void ReportAppRecoverResult(const int32_t appId, const AppExecFwk::ApplicationInfo &appInfo,
const std::string& abilityName, const std::string& result);
void AppRecoverKill(pid_t pid, int32_t reason);
/**
* Check if Caller is allowed to start ServiceAbility(FA) or ServiceExtension(Stage) or DataShareExtension(Stage).
*
@@ -203,8 +203,9 @@ public:
*
* @param msgId the msg id in ability record
* @param abilityRecordId the id of ability record
* @param isHalf is half
*/
void OnTimeOut(uint32_t msgId, int64_t abilityRecordId);
void OnTimeOut(uint32_t msgId, int64_t abilityRecordId, bool isHalf = false);
/**
* @brief handle when ability died
@@ -410,7 +411,7 @@ private:
const std::shared_ptr<Mission> &mission);
void MoveMissionListToTop(const std::shared_ptr<MissionList> &missionList);
void MoveNoneTopMissionToDefaultList(const std::shared_ptr<Mission> &mission);
void PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &ability, uint32_t msgId);
void PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &ability, uint32_t msgId, bool isHalf = false);
int DispatchState(const std::shared_ptr<AbilityRecord> &abilityRecord, int state);
int DispatchForeground(const std::shared_ptr<AbilityRecord> &abilityRecord, bool success,
@@ -132,8 +132,9 @@ public:
*
* @param msgId the msg id in ability record
* @param abilityRecordId the id of ability record
* @param isHalf is half
*/
void OnTimeOut(uint32_t msgId, int64_t abilityRecordId);
void OnTimeOut(uint32_t msgId, int64_t abilityRecordId, bool isHalf = false);
/**
* @brief handle when ability died
@@ -226,7 +227,7 @@ private:
std::string errorReason);
void MoveToBackground(const std::shared_ptr<AbilityRecord> &abilityRecord);
void CompleteBackground(const std::shared_ptr<AbilityRecord> &abilityRecord);
void PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &ability, uint32_t msgId);
void PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &ability, uint32_t msgId, bool isHalf = false);
void DelayCompleteTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord);
void CompleteTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord);
bool IsContainsAbilityInner(const sptr<IRemoteObject> &token) const;
@@ -22,6 +22,7 @@
#include "ability_manager_errors.h"
#include "ability_manager_service.h"
#include "ability_util.h"
#include "appfreeze_manager.h"
#include "hitrace_meter.h"
#include "hilog_wrapper.h"
#include "in_process_call_wrapper.h"
@@ -1810,10 +1811,12 @@ void AbilityConnectManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord>
ability->GetAbilityInfo().name.data());
return;
}
int typeId = AppExecFwk::AppfreezeManager::TypeAttribute::NORMAL_TIMEOUT;
std::string msgContent = "ability:" + ability->GetAbilityInfo().name + " ";
switch (msgId) {
case AbilityManagerService::LOAD_TIMEOUT_MSG:
msgContent += "load timeout";
typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
break;
case AbilityManagerService::ACTIVE_TIMEOUT_MSG:
msgContent += "active timeout";
@@ -1823,6 +1826,7 @@ void AbilityConnectManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord>
break;
case AbilityManagerService::FOREGROUND_TIMEOUT_MSG:
msgContent += "foreground timeout";
typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
break;
case AbilityManagerService::BACKGROUND_TIMEOUT_MSG:
msgContent += "background timeout";
@@ -1833,18 +1837,13 @@ void AbilityConnectManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord>
default:
return;
}
std::string eventType = "LIFECYCLE_TIMEOUT";
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, eventType,
OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
EVENT_KEY_UID, processInfo.uid_,
EVENT_KEY_PID, processInfo.pid_,
EVENT_KEY_PACKAGE_NAME, ability->GetAbilityInfo().bundleName,
EVENT_KEY_PROCESS_NAME, processInfo.processName_,
EVENT_KEY_MESSAGE, msgContent);
std::string eventName = AppExecFwk::AppFreezeType::LIFECYCLE_TIMEOUT;
HILOG_WARN("LIFECYCLE_TIMEOUT: uid: %{public}d, pid: %{public}d, bundleName: %{public}s, abilityName: %{public}s,"
"msg: %{public}s", processInfo.uid_, processInfo.pid_, ability->GetAbilityInfo().bundleName.c_str(),
ability->GetAbilityInfo().name.c_str(), msgContent.c_str());
AppExecFwk::AppfreezeManager::GetInstance()->LifecycleTimeoutHandle(
typeId, processInfo.pid_, eventName, ability->GetAbilityInfo().bundleName, msgContent);
}
void AbilityConnectManager::MoveToTerminatingMap(const std::shared_ptr<AbilityRecord>& abilityRecord)
@@ -43,7 +43,7 @@ void AbilityEventHandler::ProcessEvent(const EventWrap &event)
}
switch (event.GetEventId()) {
case AbilityManagerService::LOAD_TIMEOUT_MSG: {
ProcessLoadTimeOut(event.GetParam());
ProcessLoadTimeOut(event);
break;
}
case AbilityManagerService::ACTIVE_TIMEOUT_MSG: {
@@ -57,7 +57,7 @@ void AbilityEventHandler::ProcessEvent(const EventWrap &event)
break;
}
case AbilityManagerService::FOREGROUND_TIMEOUT_MSG: {
ProcessForegroundTimeOut(event.GetParam());
ProcessForegroundTimeOut(event);
break;
}
case AbilityManagerService::SHAREDATA_TIMEOUT_MSG: {
@@ -71,12 +71,22 @@ void AbilityEventHandler::ProcessEvent(const EventWrap &event)
}
}
void AbilityEventHandler::ProcessLoadTimeOut(int64_t abilityRecordId)
void AbilityEventHandler::ProcessLoadTimeOut(const EventWrap &event)
{
HILOG_INFO("Attach timeout.");
auto server = server_.lock();
CHECK_POINTER(server);
server->HandleLoadTimeOut(abilityRecordId);
if (event.GetRunCount() == 0) {
uint32_t timeout = event.GetTimeout();
if (timeout == 0) {
timeout = 3000; // 3000 : default timeout
}
auto eventWrap = EventWrap(AbilityManagerService::LOAD_TIMEOUT_MSG, event.GetParam());
eventWrap.SetRunCount(event.GetRunCount() + 1);
eventWrap.SetTimeout(timeout);
SendEvent(eventWrap, timeout);
}
server->HandleLoadTimeOut(event.GetParam(), event.GetRunCount() == 0);
}
void AbilityEventHandler::ProcessActiveTimeOut(int64_t abilityRecordId)
@@ -95,12 +105,22 @@ void AbilityEventHandler::ProcessInactiveTimeOut(int64_t abilityRecordId)
server->HandleInactiveTimeOut(abilityRecordId);
}
void AbilityEventHandler::ProcessForegroundTimeOut(int64_t abilityRecordId)
void AbilityEventHandler::ProcessForegroundTimeOut(const EventWrap &event)
{
HILOG_INFO("Foreground timeout.");
auto server = server_.lock();
CHECK_POINTER(server);
server->HandleForegroundTimeOut(abilityRecordId);
if (event.GetRunCount() == 0) {
uint32_t timeout = event.GetTimeout();
if (timeout == 0) {
timeout = 3000; // 3000 : default timeout
}
auto eventWrap = EventWrap(AbilityManagerService::FOREGROUND_TIMEOUT_MSG, event.GetParam());
eventWrap.SetRunCount(event.GetRunCount() + 1);
eventWrap.SetTimeout(timeout);
SendEvent(eventWrap, timeout);
}
server->HandleForegroundTimeOut(event.GetParam(), event.GetRunCount() == 0);
}
void AbilityEventHandler::ProcessShareDataTimeOut(int64_t uniqueId)
@@ -69,7 +69,7 @@
#include "uri_permission_manager_client.h"
#ifdef SUPPORT_GRAPHICS
#include "application_anr_listener.h"
#include "display_manager.h"
#include "input_manager.h"
#include "png.h"
@@ -320,6 +320,8 @@ bool AbilityManagerService::Init()
int amsTimeOut = AmsConfigurationParameter::GetInstance().GetAMSTimeOutTime();
HILOG_INFO("amsTimeOut is %{public}d", amsTimeOut);
#ifdef SUPPORT_GRAPHICS
auto anrListener = std::make_shared<ApplicationAnrListener>();
MMI::InputManager::GetInstance()->SetAnrObserver(anrListener);
DelayedSingleton<SystemDialogScheduler>::GetInstance()->SetDeviceType(OHOS::system::GetDeviceType());
implicitStartProcessor_ = std::make_shared<ImplicitStartProcessor>();
if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
@@ -4699,17 +4701,17 @@ bool AbilityManagerService::IsSystemUI(const std::string &bundleName) const
return bundleName == AbilityConfig::SYSTEM_UI_BUNDLE_NAME;
}
void AbilityManagerService::HandleLoadTimeOut(int64_t abilityRecordId)
void AbilityManagerService::HandleLoadTimeOut(int64_t abilityRecordId, bool isHalf)
{
HILOG_DEBUG("Handle load timeout.");
std::lock_guard<ffrt::mutex> lock(managersMutex_);
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
uiAbilityLifecycleManager_->OnTimeOut(AbilityManagerService::LOAD_TIMEOUT_MSG, abilityRecordId);
uiAbilityLifecycleManager_->OnTimeOut(AbilityManagerService::LOAD_TIMEOUT_MSG, abilityRecordId, isHalf);
return;
}
for (auto& item : missionListManagers_) {
if (item.second) {
item.second->OnTimeOut(AbilityManagerService::LOAD_TIMEOUT_MSG, abilityRecordId);
item.second->OnTimeOut(AbilityManagerService::LOAD_TIMEOUT_MSG, abilityRecordId, isHalf);
}
}
}
@@ -4742,17 +4744,17 @@ void AbilityManagerService::HandleInactiveTimeOut(int64_t abilityRecordId)
}
}
void AbilityManagerService::HandleForegroundTimeOut(int64_t abilityRecordId)
void AbilityManagerService::HandleForegroundTimeOut(int64_t abilityRecordId, bool isHalf)
{
HILOG_DEBUG("Handle foreground timeout.");
std::lock_guard<ffrt::mutex> lock(managersMutex_);
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
uiAbilityLifecycleManager_->OnTimeOut(AbilityManagerService::FOREGROUND_TIMEOUT_MSG, abilityRecordId);
uiAbilityLifecycleManager_->OnTimeOut(AbilityManagerService::FOREGROUND_TIMEOUT_MSG, abilityRecordId, isHalf);
return;
}
for (auto& item : missionListManagers_) {
if (item.second) {
item.second->OnTimeOut(AbilityManagerService::FOREGROUND_TIMEOUT_MSG, abilityRecordId);
item.second->OnTimeOut(AbilityManagerService::FOREGROUND_TIMEOUT_MSG, abilityRecordId, isHalf);
}
}
}
@@ -5526,6 +5528,28 @@ void AbilityManagerService::ReportAppRecoverResult(const int32_t appId, const Ap
"RECOVERY_RESULT", result);
}
void AbilityManagerService::AppRecoverKill(pid_t pid, int32_t reason)
{
AppExecFwk::AppFaultDataBySA faultDataSA;
faultDataSA.errorObject.name = "appRecovery";
switch (reason) {
case AppExecFwk::StateReason::CPP_CRASH:
faultDataSA.faultType = AppExecFwk::FaultDataType::CPP_CRASH;
break;
case AppExecFwk::StateReason::JS_ERROR:
faultDataSA.faultType = AppExecFwk::FaultDataType::JS_ERROR;
break;
case AppExecFwk::StateReason::LIFECYCLE:
case AppExecFwk::StateReason::APP_FREEZE:
faultDataSA.faultType = AppExecFwk::FaultDataType::APP_FREEZE;
break;
default:
faultDataSA.faultType = AppExecFwk::FaultDataType::UNKNOWN;
}
faultDataSA.pid = pid;
IN_PROCESS_CALL(DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->NotifyAppFaultBySA(faultDataSA));
}
void AbilityManagerService::ScheduleRecoverAbility(const sptr<IRemoteObject>& token, int32_t reason, const Want *want)
{
if (token == nullptr) {
@@ -5568,7 +5592,7 @@ void AbilityManagerService::ScheduleRecoverAbility(const sptr<IRemoteObject>& to
HILOG_ERROR("%{public}s AppRecovery recover app more than once in one minute, just kill app(%{public}d).",
__func__, record->GetPid());
ReportAppRecoverResult(record->GetUid(), appInfo, abilityInfo.name, "FAIL_WITHIN_ONE_MINUTE");
kill(record->GetPid(), SIGKILL);
AppRecoverKill(record->GetPid(), reason);
return;
}
@@ -5621,7 +5645,7 @@ void AbilityManagerService::ScheduleRecoverAbility(const sptr<IRemoteObject>& to
curWant.SetParam(AAFwk::Want::PARAM_ABILITY_RECOVERY_RESTART, true);
ReportAppRecoverResult(record->GetUid(), appInfo, abilityInfo.name, "SUCCESS");
kill(record->GetPid(), SIGKILL);
AppRecoverKill(record->GetPid(), reason);
}
constexpr int delaytime = 1000;
+7 -4
View File
@@ -73,6 +73,7 @@ const int32_t SEND_RESULT_CANCELED = -1;
const int VECTOR_SIZE = 2;
const int LOAD_TIMEOUT_ASANENABLED = 150;
const int TERMINATE_TIMEOUT_ASANENABLED = 150;
const int HALF_TIMEOUT = 2;
#ifdef SUPPORT_ASAN
const int COLDSTART_TIMEOUT_MULTIPLE = 150;
const int LOAD_TIMEOUT_MULTIPLE = 150;
@@ -262,10 +263,10 @@ int AbilityRecord::LoadAbility()
if (applicationInfo_.asanEnabled) {
loadTimeout =
AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * LOAD_TIMEOUT_ASANENABLED;
SendEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, loadTimeout);
SendEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, loadTimeout / HALF_TIMEOUT);
} else if (abilityInfo_.type != AppExecFwk::AbilityType::DATA) {
auto delayTime = want_.GetBoolParam("coldStart", false) ? coldStartTimeout : loadTimeout;
SendEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, delayTime);
SendEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, delayTime / HALF_TIMEOUT);
}
startTime_ = AbilityUtil::SystemTimeMillis();
@@ -338,7 +339,7 @@ void AbilityRecord::ForegroundAbility(uint32_t sceneFlag)
int foregroundTimeout =
AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * FOREGROUND_TIMEOUT_MULTIPLE;
SendEvent(AbilityManagerService::FOREGROUND_TIMEOUT_MSG, foregroundTimeout);
SendEvent(AbilityManagerService::FOREGROUND_TIMEOUT_MSG, foregroundTimeout / HALF_TIMEOUT);
// schedule active after updating AbilityState and sending timeout message to avoid ability async callback
// earlier than above actions.
@@ -2109,7 +2110,9 @@ void AbilityRecord::SendEvent(uint32_t msg, uint32_t timeOut, int32_t param)
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
CHECK_POINTER(handler);
param = (param == -1) ? recordId_ : param;
handler->SendEvent(EventWrap(msg, param), timeOut);
auto eventWrap = EventWrap(msg, param);
eventWrap.SetTimeout(timeOut);
handler->SendEvent(eventWrap, timeOut);
}
void AbilityRecord::SetStartSetting(const std::shared_ptr<AbilityStartSetting> &setting)
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -15,7 +15,12 @@
#include "application_anr_listener.h"
#include "ability_manager_service.h"
#include <sys/time.h>
#include "singleton.h"
#include "app_mgr_client.h"
#include "fault_data.h"
#include "hilog_wrapper.h"
namespace OHOS {
namespace AAFwk {
@@ -25,7 +30,16 @@ ApplicationAnrListener::~ApplicationAnrListener() {}
void ApplicationAnrListener::OnAnr(int32_t pid) const
{
DelayedSingleton<AbilityManagerService>::GetInstance()->SendANRProcessID(pid);
AppExecFwk::AppFaultDataBySA faultData;
faultData.faultType = AppExecFwk::FaultDataType::APP_FREEZE;
faultData.pid = pid;
faultData.errorObject.message = "User input does not respond!";
faultData.errorObject.stack = "";
faultData.errorObject.name = AppExecFwk::AppFreezeType::APP_INPUT_BLOCK;
faultData.waitSaveState = false;
faultData.notifyApp = false;
faultData.forceExit = false;
DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->NotifyAppFaultBySA(faultData);
}
} // namespace AAFwk
} // namespace OHOS
} // namespace OHOS
@@ -21,6 +21,7 @@
#include "ability_manager_service.h"
#include "ability_util.h"
#include "app_exit_reason_data_manager.h"
#include "appfreeze_manager.h"
#include "hitrace_meter.h"
#include "errors.h"
#include "hilog_wrapper.h"
@@ -2027,7 +2028,7 @@ void MissionListManager::PostMissionLabelUpdateTask(int missionId) const
handler->SubmitTask(task, "NotifyMissionLabelUpdated.", DELAY_NOTIFY_LABEL_TIME);
}
void MissionListManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &ability, uint32_t msgId)
void MissionListManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &ability, uint32_t msgId, bool isHalf)
{
if (ability == nullptr) {
HILOG_ERROR("ability is nullptr");
@@ -2041,10 +2042,12 @@ void MissionListManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &a
ability->GetAbilityInfo().name.data());
return;
}
int typeId = AppExecFwk::AppfreezeManager::TypeAttribute::NORMAL_TIMEOUT;
std::string msgContent = "ability:" + ability->GetAbilityInfo().name + " ";
switch (msgId) {
case AbilityManagerService::LOAD_TIMEOUT_MSG:
msgContent += "load timeout";
typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
break;
case AbilityManagerService::ACTIVE_TIMEOUT_MSG:
msgContent += "active timeout";
@@ -2054,6 +2057,7 @@ void MissionListManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &a
break;
case AbilityManagerService::FOREGROUND_TIMEOUT_MSG:
msgContent += "foreground timeout";
typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
break;
case AbilityManagerService::BACKGROUND_TIMEOUT_MSG:
msgContent += "background timeout";
@@ -2064,18 +2068,16 @@ void MissionListManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &a
default:
return;
}
std::string eventType = "LIFECYCLE_TIMEOUT";
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, eventType,
OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
EVENT_KEY_UID, processInfo.uid_,
EVENT_KEY_PID, processInfo.pid_,
EVENT_KEY_PACKAGE_NAME, ability->GetAbilityInfo().bundleName,
EVENT_KEY_PROCESS_NAME, processInfo.processName_,
EVENT_KEY_MESSAGE, msgContent);
HILOG_WARN("LIFECYCLE_TIMEOUT: uid: %{public}d, pid: %{public}d, bundleName: %{public}s, abilityName: %{public}s,"
"msg: %{public}s", processInfo.uid_, processInfo.pid_, ability->GetAbilityInfo().bundleName.c_str(),
std::string eventName = isHalf ?
AppExecFwk::AppFreezeType::LIFECYCLE_HALF_TIMEOUT : AppExecFwk::AppFreezeType::LIFECYCLE_TIMEOUT;
HILOG_WARN("%{public}s: uid: %{public}d, pid: %{public}d, bundleName: %{public}s, abilityName: %{public}s,"
"msg: %{public}s", eventName.c_str(),
processInfo.uid_, processInfo.pid_, ability->GetAbilityInfo().bundleName.c_str(),
ability->GetAbilityInfo().name.c_str(), msgContent.c_str());
AppExecFwk::AppfreezeManager::GetInstance()->LifecycleTimeoutHandle(
typeId, processInfo.pid_, eventName, ability->GetAbilityInfo().bundleName, msgContent);
}
void MissionListManager::UpdateMissionSnapshot(const std::shared_ptr<AbilityRecord>& abilityRecord) const
@@ -2095,7 +2097,7 @@ void MissionListManager::UpdateMissionSnapshot(const std::shared_ptr<AbilityReco
}
}
void MissionListManager::OnTimeOut(uint32_t msgId, int64_t abilityRecordId)
void MissionListManager::OnTimeOut(uint32_t msgId, int64_t abilityRecordId, bool isHalf)
{
HILOG_INFO("On timeout, msgId is %{public}d", msgId);
std::lock_guard guard(managerLock_);
@@ -2113,7 +2115,10 @@ void MissionListManager::OnTimeOut(uint32_t msgId, int64_t abilityRecordId)
}
#endif
PrintTimeOutLog(abilityRecord, msgId);
PrintTimeOutLog(abilityRecord, msgId, isHalf);
if (isHalf) {
return;
}
switch (msgId) {
case AbilityManagerService::LOAD_TIMEOUT_MSG:
HandleLoadTimeout(abilityRecord);
@@ -17,6 +17,7 @@
#include "ability_manager_service.h"
#include "ability_util.h"
#include "appfreeze_manager.h"
#include "errors.h"
#include "hilog_wrapper.h"
#include "hitrace_meter.h"
@@ -663,7 +664,8 @@ void UIAbilityLifecycleManager::NotifyAbilityToken(const sptr<IRemoteObject> &to
}
}
void UIAbilityLifecycleManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &ability, uint32_t msgId)
void UIAbilityLifecycleManager::PrintTimeOutLog(const std::shared_ptr<AbilityRecord> &ability,
uint32_t msgId, bool isHalf)
{
if (ability == nullptr) {
HILOG_ERROR("failed, ability is nullptr");
@@ -677,13 +679,16 @@ void UIAbilityLifecycleManager::PrintTimeOutLog(const std::shared_ptr<AbilityRec
ability->GetAbilityInfo().name.data());
return;
}
int typeId = AppExecFwk::AppfreezeManager::TypeAttribute::NORMAL_TIMEOUT;
std::string msgContent = "ability:" + ability->GetAbilityInfo().name + " ";
switch (msgId) {
case AbilityManagerService::LOAD_TIMEOUT_MSG:
msgContent += "load timeout";
typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
break;
case AbilityManagerService::FOREGROUND_TIMEOUT_MSG:
msgContent += "foreground timeout";
typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
break;
case AbilityManagerService::BACKGROUND_TIMEOUT_MSG:
msgContent += "background timeout";
@@ -694,18 +699,16 @@ void UIAbilityLifecycleManager::PrintTimeOutLog(const std::shared_ptr<AbilityRec
default:
return;
}
std::string eventType = "LIFECYCLE_TIMEOUT";
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, eventType,
OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
EVENT_KEY_UID, processInfo.uid_,
EVENT_KEY_PID, processInfo.pid_,
EVENT_KEY_PACKAGE_NAME, ability->GetAbilityInfo().bundleName,
EVENT_KEY_PROCESS_NAME, processInfo.processName_,
EVENT_KEY_MESSAGE, msgContent);
HILOG_WARN("LIFECYCLE_TIMEOUT: uid: %{public}d, pid: %{public}d, bundleName: %{public}s, abilityName: %{public}s,"
"msg: %{public}s", processInfo.uid_, processInfo.pid_, ability->GetAbilityInfo().bundleName.c_str(),
std::string eventName = isHalf ?
AppExecFwk::AppFreezeType::LIFECYCLE_HALF_TIMEOUT : AppExecFwk::AppFreezeType::LIFECYCLE_TIMEOUT;
HILOG_WARN("%{public}s: uid: %{public}d, pid: %{public}d, bundleName: %{public}s, abilityName: %{public}s,"
"msg: %{public}s", eventName.c_str(),
processInfo.uid_, processInfo.pid_, ability->GetAbilityInfo().bundleName.c_str(),
ability->GetAbilityInfo().name.c_str(), msgContent.c_str());
AppExecFwk::AppfreezeManager::GetInstance()->LifecycleTimeoutHandle(
typeId, processInfo.pid_, eventName, ability->GetAbilityInfo().bundleName, msgContent);
}
void UIAbilityLifecycleManager::CompleteBackground(const std::shared_ptr<AbilityRecord> &abilityRecord)
@@ -913,7 +916,7 @@ void UIAbilityLifecycleManager::ReportEventToSuspendManager(const AppExecFwk::Ab
#endif // EFFICIENCY_MANAGER_ENABLE
}
void UIAbilityLifecycleManager::OnTimeOut(uint32_t msgId, int64_t abilityRecordId)
void UIAbilityLifecycleManager::OnTimeOut(uint32_t msgId, int64_t abilityRecordId, bool isHalf)
{
HILOG_DEBUG("call, msgId is %{public}d", msgId);
std::lock_guard<ffrt::mutex> guard(sessionLock_);
@@ -930,7 +933,10 @@ void UIAbilityLifecycleManager::OnTimeOut(uint32_t msgId, int64_t abilityRecordI
}
HILOG_DEBUG("call, msgId:%{public}d, name:%{public}s", msgId, abilityRecord->GetAbilityInfo().name.c_str());
PrintTimeOutLog(abilityRecord, msgId);
PrintTimeOutLog(abilityRecord, msgId, isHalf);
if (isHalf) {
return;
}
switch (msgId) {
case AbilityManagerService::LOAD_TIMEOUT_MSG:
HandleLoadTimeout(abilityRecord);
@@ -945,6 +945,10 @@ private:
void SetOverlayInfo(const std::string& bundleName, const int32_t userId, AppSpawnStartMsg& startMsg);
void TimeoutNotifyApp(int32_t pid, int32_t uid, const std::string& bundleName, const FaultData &faultData);
void AppRecoveryNotifyApp(int32_t pid, const std::string& bundleName,
FaultDataType faultType, const std::string& markers);
private:
/**
* Notify application status.
+141 -26
View File
@@ -28,6 +28,7 @@
#include "app_mgr_service.h"
#include "app_process_data.h"
#include "app_state_observer_manager.h"
#include "appfreeze_manager.h"
#include "application_state_observer_stub.h"
#include "appspawn_mount_permission.h"
#include "bundle_constants.h"
@@ -111,7 +112,6 @@ constexpr int32_t RESTART_INTERVAL_TIME = 120000;
constexpr ErrCode APPMGR_ERR_OFFSET = ErrCodeOffset(SUBSYS_APPEXECFWK, 0x01);
constexpr ErrCode ERR_ALREADY_EXIST_RENDER = APPMGR_ERR_OFFSET + 100; // error code for already exist render.
const std::string EVENT_NAME_LIFECYCLE_TIMEOUT = "APP_LIFECYCLE_TIMEOUT";
constexpr char EVENT_KEY_UID[] = "UID";
constexpr char EVENT_KEY_PID[] = "PID";
constexpr char EVENT_KEY_PACKAGE_NAME[] = "PACKAGE_NAME";
@@ -3025,46 +3025,43 @@ void AppMgrServiceInner::SendHiSysEvent(const int32_t innerEventId, const int64_
return;
}
std::string eventName = EVENT_NAME_LIFECYCLE_TIMEOUT;
std::string eventName = AppExecFwk::AppFreezeType::LIFECYCLE_TIMEOUT;
int32_t pid = appRecord->GetPriorityObject()->GetPid();
int32_t uid = appRecord->GetUid();
std::string packageName = appRecord->GetBundleName();
std::string processName = appRecord->GetProcessName();
std::string msg;
std::string msg = AppExecFwk::AppFreezeType::APP_LIFECYCLE_TIMEOUT;
msg += ",";
int typeId = AppExecFwk::AppfreezeManager::TypeAttribute::NORMAL_TIMEOUT;
switch (innerEventId) {
case AMSEventHandler::TERMINATE_ABILITY_TIMEOUT_MSG:
msg = EVENT_MESSAGE_TERMINATE_ABILITY_TIMEOUT;
msg += EVENT_MESSAGE_TERMINATE_ABILITY_TIMEOUT;
break;
case AMSEventHandler::TERMINATE_APPLICATION_TIMEOUT_MSG:
msg = EVENT_MESSAGE_TERMINATE_APPLICATION_TIMEOUT;
msg += EVENT_MESSAGE_TERMINATE_APPLICATION_TIMEOUT;
break;
case AMSEventHandler::ADD_ABILITY_STAGE_INFO_TIMEOUT_MSG:
msg = EVENT_MESSAGE_ADD_ABILITY_STAGE_INFO_TIMEOUT;
msg += EVENT_MESSAGE_ADD_ABILITY_STAGE_INFO_TIMEOUT;
typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
break;
case AMSEventHandler::START_PROCESS_SPECIFIED_ABILITY_TIMEOUT_MSG:
msg = EVENT_MESSAGE_START_PROCESS_SPECIFIED_ABILITY_TIMEOUT;
msg += EVENT_MESSAGE_START_PROCESS_SPECIFIED_ABILITY_TIMEOUT;
typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
break;
case AMSEventHandler::START_SPECIFIED_ABILITY_TIMEOUT_MSG:
msg = EVENT_MESSAGE_START_SPECIFIED_ABILITY_TIMEOUT;
msg += EVENT_MESSAGE_START_SPECIFIED_ABILITY_TIMEOUT;
typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
break;
default:
msg = EVENT_MESSAGE_DEFAULT;
msg += EVENT_MESSAGE_DEFAULT;
break;
}
HILOG_DEBUG("SendHiSysEvent, eventName = %{public}s, uid = %{public}d, pid = %{public}d, \
HILOG_WARN("LIFECYCLE_TIMEOUT, eventName = %{public}s, uid = %{public}d, pid = %{public}d, \
packageName = %{public}s, processName = %{public}s, msg = %{public}s",
eventName.c_str(), uid, pid, packageName.c_str(), processName.c_str(), msg.c_str());
HiSysEventWrite(
OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK,
eventName,
OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
EVENT_KEY_PID, pid,
EVENT_KEY_UID, uid,
EVENT_KEY_PACKAGE_NAME, packageName,
EVENT_KEY_PROCESS_NAME, processName,
EVENT_KEY_MESSAGE, msg);
AppExecFwk::AppfreezeManager::GetInstance()->LifecycleTimeoutHandle(
typeId, pid, eventName, packageName, msg);
}
int AppMgrServiceInner::GetAbilityRecordsByProcessID(const int pid, std::vector<sptr<IRemoteObject>> &tokens)
@@ -3739,6 +3736,44 @@ int32_t AppMgrServiceInner::NotifyUnLoadRepairPatch(const std::string &bundleNam
return appRunningManager_->NotifyUnLoadRepairPatch(bundleName, callback);
}
void AppMgrServiceInner::AppRecoveryNotifyApp(int32_t pid, const std::string& bundleName,
FaultDataType faultType, const std::string& markers)
{
HILOG_INFO("AppRecovery NotifyApp to kill is: bundleName: %{public}s, faultType: %{public}d, pid: %{public}d",
bundleName.c_str(), faultType, pid);
if (faultType != FaultDataType::APP_FREEZE) {
KillProcessByPid(pid);
return;
}
std::string timeOutName = "waitSaveTask" + std::to_string(pid) + bundleName;
if (markers == "appRecovery") {
if (taskHandler_->CancelTask(timeOutName)) {
KillProcessByPid(pid);
}
return;
}
if (markers != "recoveryTimeout") {
return;
}
auto waitSaveTask = [pid, bundleName, innerService = shared_from_this()]() {
auto appRecord = innerService->GetAppRunningRecordByPid(pid);
if (appRecord == nullptr) {
HILOG_ERROR("no such appRecord");
return;
}
std::string name = appRecord->GetBundleName();
if (bundleName == name) {
HILOG_INFO("waitSaveTask timeout %{public}s,pid == %{public}d is going to exit due to AppRecovery.",
bundleName.c_str(), pid);
innerService->KillProcessByPid(pid);
}
};
constexpr int32_t timeOut = 2000;
taskHandler_->SubmitTask(waitSaveTask, timeOutName, timeOut);
}
int32_t AppMgrServiceInner::NotifyAppFault(const FaultData &faultData)
{
HILOG_DEBUG("called.");
@@ -3750,12 +3785,68 @@ int32_t AppMgrServiceInner::NotifyAppFault(const FaultData &faultData)
return ERR_INVALID_VALUE;
}
std::string bundleName = appRecord->GetBundleName();
HILOG_DEBUG("FaultData is: error name: %{public}s, faultType: %{public}s, uid: %{public}d, pid: %{public}d,\
bundleName: %{public}s", faultData.errorObject.name.c_str(), FaultTypeToString(faultData.faultType).c_str(),
callerUid, pid, bundleName.c_str());
if (faultData.faultType == FaultDataType::APP_FREEZE) {
if (faultData.timeoutMarkers != "") {
if (!taskHandler_->CancelTask(faultData.timeoutMarkers)) {
return ERR_OK;
}
}
if (faultData.waitSaveState) {
AppRecoveryNotifyApp(pid, bundleName, FaultDataType::APP_FREEZE, "recoveryTimeout");
}
}
auto notifyAppTask = [appRecord, pid, callerUid, bundleName, faultData, innerService = shared_from_this()]() {
if (faultData.faultType == FaultDataType::APP_FREEZE) {
AppfreezeManager::AppInfo info = {
.pid = pid,
.uid = callerUid,
.bundleName = bundleName,
.processName = bundleName,
};
auto appfreezeManager = AppExecFwk::AppfreezeManager::GetInstance();
if (!appfreezeManager->IsHandleAppfreeze(bundleName)) {
return;
}
appfreezeManager->AppfreezeHandle(faultData, info);
}
HILOG_WARN("FaultData is: name: %{public}s, faultType: %{public}d, uid: %{public}d, pid: %{public}d,"
"bundleName: %{public}s, faultData.forceExit==%{public}d, faultData.waitSaveState==%{public}d",
faultData.errorObject.name.c_str(), faultData.faultType,
callerUid, pid, bundleName.c_str(), faultData.forceExit, faultData.waitSaveState);
if (faultData.forceExit && !faultData.waitSaveState && appRecord->IsKeepAliveApp()) {
HILOG_INFO("FaultData %{public}s,pid == %{public}d is going to exit due to %{public}s.",
bundleName.c_str(), pid, innerService->FaultTypeToString(faultData.faultType).c_str());
innerService->KillProcessByPid(pid);
return;
}
};
taskHandler_->SubmitTask(notifyAppTask, "notifyAppFaultTask");
return ERR_OK;
}
void AppMgrServiceInner::TimeoutNotifyApp(int32_t pid, int32_t uid,
const std::string& bundleName, const FaultData &faultData)
{
if (faultData.faultType == FaultDataType::APP_FREEZE) {
AppfreezeManager::AppInfo info = {
.pid = pid,
.uid = uid,
.bundleName = bundleName,
.processName = bundleName,
};
AppExecFwk::AppfreezeManager::GetInstance()->AppfreezeHandleWithStack(faultData, info);
}
HILOG_WARN("FaultData timeout NotifyApp %{public}s is going to exit due to %{public}s.",
bundleName.c_str(), FaultTypeToString(faultData.faultType).c_str());
KillProcessByPid(pid);
}
int32_t AppMgrServiceInner::NotifyAppFaultBySA(const AppFaultDataBySA &faultData)
{
HILOG_DEBUG("called");
@@ -3776,14 +3867,34 @@ int32_t AppMgrServiceInner::NotifyAppFaultBySA(const AppFaultDataBySA &faultData
HILOG_ERROR("no such appRecord");
return ERR_INVALID_VALUE;
}
int64_t time = SystemTimeMillisecond();
FaultData transformedFaultData = ConvertDataTypes(faultData);
int32_t uid = appRecord->GetUid();
std::string bundleName = appRecord->GetBundleName();
HILOG_DEBUG("FaultDataBySA is: error name: %{public}s, faultType: %{public}s, uid: %{public}d,\
pid: %{public}d, bundleName: %{public}s",
if (faultData.errorObject.name == "appRecovery") {
AppRecoveryNotifyApp(pid, bundleName, faultData.faultType, "appRecovery");
return ERR_OK;
}
if (transformedFaultData.timeoutMarkers.empty()) {
transformedFaultData.timeoutMarkers = "notifyFault" + std::to_string(pid) + "-" + std::to_string(time);
}
const int64_t timeout = 3000;
if (faultData.faultType == FaultDataType::APP_FREEZE) {
if (!AppExecFwk::AppfreezeManager::GetInstance()->IsHandleAppfreeze(bundleName)) {
return ERR_OK;
}
auto timeoutNotifyApp = std::bind(&AppMgrServiceInner::TimeoutNotifyApp, this,
pid, uid, bundleName, transformedFaultData);
taskHandler_->SubmitTask(timeoutNotifyApp, transformedFaultData.timeoutMarkers, timeout);
}
appRecord->NotifyAppFault(transformedFaultData);
HILOG_WARN("FaultDataBySA is: name: %{public}s, faultType: %{public}s, uid: %{public}d,"
"pid: %{public}d, bundleName: %{public}s",
faultData.errorObject.name.c_str(), FaultTypeToString(faultData.faultType).c_str(),
uid, pid, bundleName.c_str());
appRecord->NotifyAppFault(transformedFaultData);
} else {
HILOG_DEBUG("this is not called by SA.");
return AAFwk::CHECK_PERMISSION_FAILED;
@@ -3796,6 +3907,10 @@ FaultData AppMgrServiceInner::ConvertDataTypes(const AppFaultDataBySA &faultData
FaultData newfaultData;
newfaultData.faultType = faultData.faultType;
newfaultData.errorObject = faultData.errorObject;
newfaultData.timeoutMarkers = faultData.timeoutMarkers;
newfaultData.waitSaveState = faultData.waitSaveState;
newfaultData.notifyApp = faultData.notifyApp;
newfaultData.forceExit = faultData.forceExit;
return newfaultData;
}
@@ -71,11 +71,29 @@ public:
{
return eventData_ == other.eventData_;
}
void SetRunCount(int runCount)
{
runCount_ = runCount;
}
int GetRunCount() const
{
return runCount_;
}
void SetTimeout(uint32_t timeout)
{
timeout_ = timeout;
}
uint32_t GetTimeout() const
{
return timeout_;
}
private:
uint32_t eventId_;
int64_t param_;
std::shared_ptr<EventDataBase> eventData_;
TaskHandle eventTask_;
int runCount_ = 0;
uint32_t timeout_ = 0;
};
class EventHandlerWrap : public std::enable_shared_from_this<EventHandlerWrap> {
@@ -2193,7 +2193,7 @@ HWTEST_F(MainThreadTest, HandleOnOverlayChanged_0100, TestSize.Level1)
HWTEST_F(MainThreadTest, ScheduleNotifyAppFault_0100, TestSize.Level1)
{
FaultData faultData;
faultData.faultType = FaultDataType::APP_FREEZE;
faultData.faultType = FaultDataType::JS_ERROR;
faultData.errorObject.message = "msgContent";
faultData.errorObject.stack = "stack";
faultData.errorObject.name = "eventType";
+24 -2
View File
@@ -82,7 +82,19 @@ HWTEST_F(FaultDataTest, ReadFromParcel_001, TestSize.Level1)
messageFifth.WriteString(helloWord);
messageFifth.WriteInt32(12);
bool retFifth = faultData->ReadFromParcel(messageFifth);
EXPECT_EQ(true, retFifth);
EXPECT_EQ(false, retFifth);
MessageParcel messageSixth;
messageSixth.WriteString(helloWord);
messageSixth.WriteString(helloWord);
messageSixth.WriteString(helloWord);
messageSixth.WriteInt32(12);
messageSixth.WriteString(helloWord);
messageSixth.WriteBool(true);
messageSixth.WriteBool(true);
messageSixth.WriteBool(true);
bool retSixth = faultData->ReadFromParcel(messageSixth);
EXPECT_EQ(true, retSixth);
}
/**
@@ -102,6 +114,10 @@ HWTEST_F(FaultDataTest, Unmarshalling_001, TestSize.Level1)
message.WriteString(helloWord);
message.WriteString(helloWord);
message.WriteInt32(12);
message.WriteString(helloWord);
message.WriteBool(true);
message.WriteBool(true);
message.WriteBool(true);
auto retSecond = faultData->Unmarshalling(message);
EXPECT_NE(nullptr, retSecond);
}
@@ -168,6 +184,10 @@ HWTEST_F(FaultDataTest, ReadFromParcel_002, TestSize.Level1)
messageSixth.WriteString(helloWord);
messageSixth.WriteInt32(12);
messageSixth.WriteInt32(34);
messageSixth.WriteString(helloWord);
messageSixth.WriteBool(true);
messageSixth.WriteBool(true);
messageSixth.WriteBool(true);
bool retSixth = appFaultDataBySA->ReadFromParcel(messageSixth);
EXPECT_EQ(true, retSixth);
}
@@ -190,8 +210,10 @@ HWTEST_F(FaultDataTest, Unmarshalling_002, TestSize.Level1)
message.WriteString(helloWord);
message.WriteInt32(12);
message.WriteInt32(34);
message.WriteInt32(56);
message.WriteString(helloWord);
message.WriteBool(true);
message.WriteBool(true);
message.WriteBool(true);
auto retSecond = appFaultDataBySA->Unmarshalling(message);
EXPECT_NE(nullptr, retSecond);
}
@@ -41,7 +41,6 @@ public:
std::shared_ptr<MockHandler> mockHandler_ = nullptr;
std::shared_ptr<EventRunner> runner_ = nullptr;
std::shared_ptr<Watchdog> watchdog_ = nullptr;
std::shared_ptr<MainHandlerDumper> mainHandlerDumper_;
static void SetUpTestCase(void);
static void TearDownTestCase(void);
void SetUp();
@@ -61,13 +60,11 @@ void WatchdogTest::SetUp(void)
watchdog_ = std::make_shared<Watchdog>();
watchdog_->Init(mockHandler_);
mainHandlerDumper_ = std::make_shared<MainHandlerDumper>();
}
void WatchdogTest::TearDown(void)
{
watchdog_->Stop();
mainHandlerDumper_ = nullptr;
}
/**
@@ -108,8 +105,6 @@ HWTEST_F(WatchdogTest, AppExecFwk_watchdog_ReportEvent_0001, Function | MediumTe
// be ready for ReportEvent
watchdog_->lastWatchTime_ = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::
steady_clock::now().time_since_epoch()).count() - TEST_INTERVAL_TIME;
std::shared_ptr<ApplicationInfo> application = std::make_shared<ApplicationInfo>();
watchdog_->SetApplicationInfo(application);
watchdog_->needReport_ = true;
watchdog_->isSixSecondEvent_.store(true);
@@ -129,8 +124,6 @@ HWTEST_F(WatchdogTest, AppExecFwk_watchdog_ReportEvent_0002, Function | MediumTe
// be ready for ReportEvent
watchdog_->lastWatchTime_ = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::
system_clock::now().time_since_epoch()).count() - TEST_INTERVAL_TIME;
std::shared_ptr<ApplicationInfo> application = std::make_shared<ApplicationInfo>();
watchdog_->SetApplicationInfo(application);
watchdog_->needReport_ = true;
watchdog_->isSixSecondEvent_.store(false);
@@ -198,21 +191,6 @@ HWTEST_F(WatchdogTest, WatchdogTest_Stop_002, TestSize.Level1)
GTEST_LOG_(INFO) << "WatchdogTest_Stop_002 end";
}
/**
* @tc.number: WatchdogTest_SetApplicationInfo_001
* @tc.name: SetApplicationInfo
* @tc.desc: Verify that function SetApplicationInfo.
*/
HWTEST_F(WatchdogTest, WatchdogTest_SetApplicationInfo_001, TestSize.Level1)
{
GTEST_LOG_(INFO) << "WatchdogTest_SetApplicationInfo_001 start";
std::shared_ptr<ApplicationInfo> applicationInfo = std::make_shared<ApplicationInfo>();
EXPECT_TRUE(watchdog_->applicationInfo_ == nullptr);
watchdog_->SetApplicationInfo(applicationInfo);
EXPECT_TRUE(watchdog_->applicationInfo_ != nullptr);
GTEST_LOG_(INFO) << "WatchdogTest_SetApplicationInfo_001 end";
}
/**
* @tc.number: WatchdogTest_SetAppMainThreadState_001
* @tc.name: SetAppMainThreadState
@@ -397,7 +375,7 @@ HWTEST_F(WatchdogTest, WatchdogTest_ReportEvent_004, TestSize.Level1)
watchdog_->lastWatchTime_ = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch()).count();
watchdog_->ReportEvent();
EXPECT_TRUE(watchdog_->applicationInfo_ == nullptr);
EXPECT_TRUE(watchdog_->appMainHandler_ != nullptr);
GTEST_LOG_(INFO) << "WatchdogTest_ReportEvent_002 end";
}
@@ -411,10 +389,8 @@ HWTEST_F(WatchdogTest, WatchdogTest_ReportEvent_005, TestSize.Level1)
GTEST_LOG_(INFO) << "WatchdogTest_ReportEvent_005 start";
watchdog_->lastWatchTime_ = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch()).count();
watchdog_->applicationInfo_ = std::make_shared<ApplicationInfo>();
watchdog_->needReport_ = false;
watchdog_->ReportEvent();
EXPECT_TRUE(watchdog_->applicationInfo_ != nullptr);
EXPECT_TRUE(watchdog_->needReport_ == false);
GTEST_LOG_(INFO) << "WatchdogTest_ReportEvent_005 end";
}
@@ -429,10 +405,8 @@ HWTEST_F(WatchdogTest, WatchdogTest_ReportEvent_006, TestSize.Level1)
GTEST_LOG_(INFO) << "WatchdogTest_ReportEvent_006 start";
watchdog_->lastWatchTime_ = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch()).count();
watchdog_->applicationInfo_ = std::make_shared<ApplicationInfo>();
watchdog_->isSixSecondEvent_ = true;
watchdog_->ReportEvent();
EXPECT_TRUE(watchdog_->applicationInfo_ != nullptr);
EXPECT_TRUE(watchdog_->needReport_);
GTEST_LOG_(INFO) << "WatchdogTest_ReportEvent_006 end";
}
@@ -447,40 +421,11 @@ HWTEST_F(WatchdogTest, WatchdogTest_ReportEvent_007, TestSize.Level1)
GTEST_LOG_(INFO) << "WatchdogTest_ReportEvent_007 start";
watchdog_->lastWatchTime_ = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch()).count();
watchdog_->applicationInfo_ = std::make_shared<ApplicationInfo>();
watchdog_->ReportEvent();
EXPECT_TRUE(watchdog_->applicationInfo_ != nullptr);
EXPECT_FALSE(watchdog_->isSixSecondEvent_);
GTEST_LOG_(INFO) << "WatchdogTest_ReportEvent_007 end";
}
/**
* @tc.number: WatchdogTest_Dump_001
* @tc.name: Dump
* @tc.desc: Verify that function Dump.
*/
HWTEST_F(WatchdogTest, WatchdogTest_Dump_001, TestSize.Level1)
{
GTEST_LOG_(INFO) << "WatchdogTest_Dump_001 start";
std::string message = "message";
mainHandlerDumper_->dumpInfo = "dump";
mainHandlerDumper_->Dump(message);
EXPECT_EQ(mainHandlerDumper_->GetDumpInfo(), "dumpmessage");
GTEST_LOG_(INFO) << "WatchdogTest_Dump_001 end";
}
/**
* @tc.number: WatchdogTest_GetTag_001
* @tc.name: GetTag
* @tc.desc: Verify that function GetTag.
*/
HWTEST_F(WatchdogTest, WatchdogTest_GetTag_001, TestSize.Level1)
{
GTEST_LOG_(INFO) << "WatchdogTest_GetTag_001 start";
EXPECT_EQ(mainHandlerDumper_->GetTag(), "");
GTEST_LOG_(INFO) << "WatchdogTest_GetTag_001 end";
}
/**
* @tc.number: WatchdogTest_ReportEvent_008
* @tc.name: ReportEvent
@@ -491,7 +436,6 @@ HWTEST_F(WatchdogTest, WatchdogTest_ReportEvent_008, TestSize.Level1)
watchdog_->lastWatchTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::
system_clock::now().time_since_epoch()).count() - TEST_INTERVAL_TIME;
std::shared_ptr<EventHandler> eventHandler = std::make_shared<EventHandler>();
watchdog_->applicationInfo_ = std::make_shared<ApplicationInfo>();
watchdog_->needReport_ = true;
watchdog_->isSixSecondEvent_.store(true);
EXPECT_TRUE(watchdog_->needReport_);