From 193393ac41f60f53cd459dc246de5cbb64d8eefd Mon Sep 17 00:00:00 2001 From: hhl Date: Thu, 13 Feb 2025 19:51:28 +0800 Subject: [PATCH] Failed to capture stack, maintenance and testing. Signed-off-by: hhl --- .../native/appkit/dfr/appfreeze_inner.cpp | 18 ++++++++++ interfaces/inner_api/app_manager/BUILD.gn | 1 + .../kits/native/appkit/dfr/appfreeze_inner.h | 1 + services/abilitymgr/BUILD.gn | 1 + services/appdfr/include/appfreeze_manager.h | 5 +-- services/appdfr/src/appfreeze_manager.cpp | 34 ++++++++++++++----- .../appdfr/src/application_anr_listener.cpp | 19 ++++++++++- .../abilityappfreezemanager_fuzzer.cpp | 4 +-- .../appfreeze_inner_test.cpp | 11 ++++++ .../appfreeze_manager_test.cpp | 15 ++++++-- 10 files changed, 94 insertions(+), 15 deletions(-) diff --git a/frameworks/native/appkit/dfr/appfreeze_inner.cpp b/frameworks/native/appkit/dfr/appfreeze_inner.cpp index 164135d980..62bdda6924 100644 --- a/frameworks/native/appkit/dfr/appfreeze_inner.cpp +++ b/frameworks/native/appkit/dfr/appfreeze_inner.cpp @@ -20,6 +20,7 @@ #include "ability_state.h" #include "appfreeze_manager.h" #include "app_recovery.h" +#include "backtrace_local.h" #include "exit_reason.h" #include "ffrt.h" #include "freeze_util.h" @@ -98,6 +99,16 @@ void AppfreezeInner::GetMainHandlerDump(std::string& msgContent) } } +std::string AppfreezeInner::GetFormatTime() +{ + auto now = std::chrono::system_clock::now(); + auto millisecs = std::chrono::duration_cast(now.time_since_epoch()); + auto start = millisecs.count(); + std::string timeStamp = "\nTimestamp:" + AbilityRuntime::TimeUtil::FormatTime("%Y-%m-%d %H:%M:%S") + + ":" + std::to_string(start % AbilityRuntime::TimeUtil::SEC_TO_MILLISEC) + "\n"; + return timeStamp; +} + void AppfreezeInner::ChangeFaultDateInfo(FaultData& faultData, const std::string& msgContent) { faultData.errorObject.message += msgContent; @@ -105,6 +116,13 @@ void AppfreezeInner::ChangeFaultDateInfo(FaultData& faultData, const std::string faultData.notifyApp = false; faultData.waitSaveState = false; faultData.forceExit = false; + int32_t pid = IPCSkeleton::GetCallingPid(); + faultData.errorObject.stack = GetFormatTime(); + std::string stack = ""; + if (!HiviewDFX::GetBacktraceStringByTidWithMix(stack, pid, 0, true)) { + stack = "Failed to dump stacktrace for " + std::to_string(pid) + "\n" + stack; + } + faultData.errorObject.stack += stack + "\n" + GetFormatTime(); bool isExit = IsExitApp(faultData.errorObject.name); if (isExit) { faultData.forceExit = true; diff --git a/interfaces/inner_api/app_manager/BUILD.gn b/interfaces/inner_api/app_manager/BUILD.gn index 3581145475..cca5cd2d22 100644 --- a/interfaces/inner_api/app_manager/BUILD.gn +++ b/interfaces/inner_api/app_manager/BUILD.gn @@ -137,6 +137,7 @@ ohos_shared_library("app_manager") { external_deps = [ "c_utils:utils", + "faultloggerd:libbacktrace_local", "faultloggerd:libdfx_dumpcatcher", "faultloggerd:libfaultloggerd", "ffrt:libffrt", diff --git a/interfaces/kits/native/appkit/dfr/appfreeze_inner.h b/interfaces/kits/native/appkit/dfr/appfreeze_inner.h index 90f4bc3bf7..fa1f1bd0fd 100644 --- a/interfaces/kits/native/appkit/dfr/appfreeze_inner.h +++ b/interfaces/kits/native/appkit/dfr/appfreeze_inner.h @@ -54,6 +54,7 @@ private: int NotifyANR(const FaultData& faultData); bool IsExitApp(const std::string& name); bool IsHandleAppfreeze(); + std::string GetFormatTime(); static std::mutex singletonMutex_; static std::shared_ptr instance_; diff --git a/services/abilitymgr/BUILD.gn b/services/abilitymgr/BUILD.gn index f5598372d7..bd3e546fb1 100644 --- a/services/abilitymgr/BUILD.gn +++ b/services/abilitymgr/BUILD.gn @@ -164,6 +164,7 @@ ohos_shared_library("abilityms") { "config_policy:configpolicy_util", "dsoftbus:softbus_client", "eventhandler:libeventhandler", + "faultloggerd:libbacktrace_local", "ffrt:libffrt", "hicollie:libhicollie", "hilog:libhilog", diff --git a/services/appdfr/include/appfreeze_manager.h b/services/appdfr/include/appfreeze_manager.h index d49065c83c..37f7cbedb9 100644 --- a/services/appdfr/include/appfreeze_manager.h +++ b/services/appdfr/include/appfreeze_manager.h @@ -116,8 +116,8 @@ private: std::set GetBinderPeerPids(std::string& stack, int pid, std::set& asyncPids, AppfreezeManager::TerminalBinder& terminalBinder) const; void FindStackByPid(std::string& ret, int pid) const; - std::string CatchJsonStacktrace(int pid, const std::string& faultType) const; - std::string CatcherStacktrace(int pid) const; + std::string CatchJsonStacktrace(int pid, const std::string& faultType, const std::string& stack) const; + std::string CatcherStacktrace(int pid, const std::string& stack) const; int AcquireStack(const FaultData& faultData, const AppInfo& appInfo, const std::string& memoryContent); int NotifyANR(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo, const std::string& binderInfo, const std::string& memoryContent); @@ -128,6 +128,7 @@ private: void ClearOldInfo(); void CollectFreezeSysMemory(std::string& memoryContent); int MergeNotifyInfo(FaultData& faultNotifyData, const AppfreezeManager::AppInfo& appInfo); + std::string GetFormatTime(); static const inline std::string LOGGER_DEBUG_PROC_PATH = "/proc/transaction_proc"; std::string name_; diff --git a/services/appdfr/src/appfreeze_manager.cpp b/services/appdfr/src/appfreeze_manager.cpp index 681e926ce3..0bac16e613 100644 --- a/services/appdfr/src/appfreeze_manager.cpp +++ b/services/appdfr/src/appfreeze_manager.cpp @@ -22,6 +22,7 @@ #include #include +#include "backtrace_local.h" #include "faultloggerd_client.h" #include "file_ex.h" #include "ffrt.h" @@ -163,7 +164,7 @@ int AppfreezeManager::MergeNotifyInfo(FaultData& faultNotifyData, const Appfreez std::string fullStackPath = ""; if (faultNotifyData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT || faultNotifyData.errorObject.name == AppFreezeType::LIFECYCLE_TIMEOUT) { - catcherStack += CatcherStacktrace(appInfo.pid); + catcherStack += CatcherStacktrace(appInfo.pid, faultNotifyData.errorObject.stack); fullStackPath = WriteToFile(fileName, catcherStack); faultNotifyData.errorObject.stack = fullStackPath; } else { @@ -171,7 +172,8 @@ int AppfreezeManager::MergeNotifyInfo(FaultData& faultNotifyData, const Appfreez std::string timeStamp = "\nTimestamp:" + AbilityRuntime::TimeUtil::FormatTime("%Y-%m-%d %H:%M:%S") + ":" + std::to_string(start % SEC_TO_MILLISEC); faultNotifyData.errorObject.message += timeStamp; - catchJsonStack += CatchJsonStacktrace(appInfo.pid, faultNotifyData.errorObject.name); + catchJsonStack += CatchJsonStacktrace(appInfo.pid, faultNotifyData.errorObject.name, + faultNotifyData.errorObject.stack); fullStackPath = WriteToFile(fileName, catchJsonStack); faultNotifyData.errorObject.stack = fullStackPath; } @@ -235,6 +237,13 @@ std::string AppfreezeManager::WriteToFile(const std::string& fileName, std::stri return stackPath; } +std::string AppfreezeManager::GetFormatTime() +{ + std::string timeStamp = "\nTimestamp:" + AbilityRuntime::TimeUtil::FormatTime("%Y-%m-%d %H:%M:%S") + + ":" + std::to_string(GetMilliseconds() % AbilityRuntime::TimeUtil::SEC_TO_MILLISEC) + "\n"; + return timeStamp; +} + int AppfreezeManager::LifecycleTimeoutHandle(const ParamInfo& info, FreezeUtil::LifecycleFlow flow) { if (info.typeId != AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT) { @@ -254,6 +263,12 @@ int AppfreezeManager::LifecycleTimeoutHandle(const ParamInfo& info, FreezeUtil:: AppFaultDataBySA faultDataSA; faultDataSA.errorObject.name = info.eventName; faultDataSA.errorObject.message = info.msg; + faultDataSA.errorObject.stack = GetFormatTime(); + std::string stack = ""; + if (!HiviewDFX::GetBacktraceStringByTidWithMix(stack, info.pid, 0, true)) { + stack = "Failed to dump stacktrace for " + stack; + } + faultDataSA.errorObject.stack += stack + "\n" + GetFormatTime(); faultDataSA.faultType = FaultDataType::APP_FREEZE; faultDataSA.timeoutMarkers = "notifyFault" + std::to_string(info.pid) + @@ -293,7 +308,7 @@ int AppfreezeManager::AcquireStack(const FaultData& faultData, continue; } std::string content = "Binder catcher stacktrace, type is peer, pid : " + std::to_string(pidTemp) + "\n"; - content += CatcherStacktrace(pidTemp); + content += CatcherStacktrace(pidTemp, ""); binderPidsStr += " " + std::to_string(pidTemp); if (terminalBinder.pid > 0 && pidTemp == terminalBinder.pid) { terminalBinder.tid = (terminalBinder.tid > 0) ? terminalBinder.tid : terminalBinder.pid; @@ -307,7 +322,7 @@ int AppfreezeManager::AcquireStack(const FaultData& faultData, TAG_LOGI(AAFwkTag::APPDFR, "AsyncBinder pidTemp pids:%{public}d", pidTemp); if (pidTemp != pid && syncPids.find(pidTemp) == syncPids.end()) { std::string content = "Binder catcher stacktrace, type is async, pid : " + std::to_string(pidTemp) + "\n"; - content += CatcherStacktrace(pidTemp); + content += CatcherStacktrace(pidTemp, ""); binderInfo += content; } } @@ -524,7 +539,8 @@ void AppfreezeManager::FindStackByPid(std::string& ret, int pid) const } } -std::string AppfreezeManager::CatchJsonStacktrace(int pid, const std::string& faultType) const +std::string AppfreezeManager::CatchJsonStacktrace(int pid, const std::string& faultType, + const std::string& stack) const { HITRACE_METER_FMT(HITRACE_TAG_APP, "CatchJsonStacktrace pid:%d", pid); HiviewDFX::DfxDumpCatcher dumplog; @@ -533,7 +549,8 @@ std::string AppfreezeManager::CatchJsonStacktrace(int pid, const std::string& fa size_t defaultMaxFaultNum = 256; if (dumplog.DumpCatchProcess(pid, msg, defaultMaxFaultNum, true) == -1) { TAG_LOGI(AAFwkTag::APPDFR, "appfreeze catch stack failed"); - ret = "Failed to dump stacktrace for " + std::to_string(pid) + "\n" + msg; + ret = "Failed to dump stacktrace for " + std::to_string(pid) + "\n" + msg + + "\nMain thread stack:" + stack; if (faultType == AppFreezeType::APP_INPUT_BLOCK) { FindStackByPid(ret, pid); } @@ -547,14 +564,15 @@ std::string AppfreezeManager::CatchJsonStacktrace(int pid, const std::string& fa return ret; } -std::string AppfreezeManager::CatcherStacktrace(int pid) const +std::string AppfreezeManager::CatcherStacktrace(int pid, const std::string& stack) const { HITRACE_METER_FMT(HITRACE_TAG_APP, "CatcherStacktrace pid:%d", pid); HiviewDFX::DfxDumpCatcher dumplog; std::string ret; std::string msg; if (dumplog.DumpCatchProcess(pid, msg) == -1) { - ret = "Failed to dump stacktrace for " + std::to_string(pid) + "\n" + msg; + ret = "Failed to dump stacktrace for " + std::to_string(pid) + "\n" + msg + + "\nMain thread stack:" + stack; } else { ret = msg; } diff --git a/services/appdfr/src/application_anr_listener.cpp b/services/appdfr/src/application_anr_listener.cpp index 1c9cf3019b..ad898d19ca 100644 --- a/services/appdfr/src/application_anr_listener.cpp +++ b/services/appdfr/src/application_anr_listener.cpp @@ -19,8 +19,10 @@ #include "singleton.h" #include "app_mgr_client.h" +#include "backtrace_local.h" #include "fault_data.h" #include "hilog_tag_wrapper.h" +#include "time_util.h" namespace OHOS { namespace AAFwk { @@ -28,13 +30,28 @@ ApplicationAnrListener::ApplicationAnrListener() {} ApplicationAnrListener::~ApplicationAnrListener() {} +std::string GetFormatTime() +{ + auto now = std::chrono::system_clock::now(); + auto millisecs = std::chrono::duration_cast(now.time_since_epoch()); + auto start = millisecs.count(); + std::string timeStamp = "\nTimestamp:" + AbilityRuntime::TimeUtil::FormatTime("%Y-%m-%d %H:%M:%S") + + ":" + std::to_string(start % AbilityRuntime::TimeUtil::SEC_TO_MILLISEC) + "\n"; + return timeStamp; +} + void ApplicationAnrListener::OnAnr(int32_t pid, int32_t eventId) const { 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.stack = GetFormatTime(); + std::string stack = ""; + if (!HiviewDFX::GetBacktraceStringByTidWithMix(stack, pid, 0, true)) { + stack = "Failed to dump stacktrace for " + std::to_string(pid) + "\n" + stack; + } + faultData.errorObject.stack += stack + "\n" + GetFormatTime(); faultData.errorObject.name = AppExecFwk::AppFreezeType::APP_INPUT_BLOCK; faultData.waitSaveState = false; faultData.notifyApp = false; diff --git a/test/fuzztest/abilityappfreezemanager_fuzzer/abilityappfreezemanager_fuzzer.cpp b/test/fuzztest/abilityappfreezemanager_fuzzer/abilityappfreezemanager_fuzzer.cpp index cf475369b9..2b6bb1fadb 100644 --- a/test/fuzztest/abilityappfreezemanager_fuzzer/abilityappfreezemanager_fuzzer.cpp +++ b/test/fuzztest/abilityappfreezemanager_fuzzer/abilityappfreezemanager_fuzzer.cpp @@ -76,8 +76,8 @@ bool DoSomethingInterestingWithMyAPI(const char* data, size_t size) std::string ret(data, size); freeze->FindStackByPid(ret, pid); std::string faultType(data, size); - freeze->CatchJsonStacktrace(pid, faultType); - freeze->CatcherStacktrace(pid); + freeze->CatchJsonStacktrace(pid, faultType, stack); + freeze->CatcherStacktrace(pid, stack); std::string memoryContent(data, size); freeze->AcquireStack(faultData, appInfo, memoryContent); std::string binderInfo(data, size); diff --git a/test/unittest/dfr_test/appfreeze_inner_test/appfreeze_inner_test.cpp b/test/unittest/dfr_test/appfreeze_inner_test/appfreeze_inner_test.cpp index 4cc4ec99ef..9e59385120 100644 --- a/test/unittest/dfr_test/appfreeze_inner_test/appfreeze_inner_test.cpp +++ b/test/unittest/dfr_test/appfreeze_inner_test/appfreeze_inner_test.cpp @@ -256,5 +256,16 @@ HWTEST_F(AppfreezeInnerTest, AppfreezeInner_AppfreezeHandleOverReportCount_001, appfreezeInner->AppfreezeHandleOverReportCount(isSixSecondEvent); EXPECT_TRUE(!isSixSecondEvent); } + +/** + * @tc.number: AppfreezeInner_GetFormatTime_001 + * @tc.name: GetFormatTime + * @tc.desc: Verify that function GetFormatTime. + */ +HWTEST_F(AppfreezeInnerTest, AppfreezeInner_GetFormatTime_001, TestSize.Level1) +{ + std::string ret = appfreezeInner->GetFormatTime(); + EXPECT_TRUE(!ret.empty()); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/test/unittest/dfr_test/appfreeze_manager_test/appfreeze_manager_test.cpp b/test/unittest/dfr_test/appfreeze_manager_test/appfreeze_manager_test.cpp index 023acb7757..2594f63aa5 100644 --- a/test/unittest/dfr_test/appfreeze_manager_test/appfreeze_manager_test.cpp +++ b/test/unittest/dfr_test/appfreeze_manager_test/appfreeze_manager_test.cpp @@ -187,9 +187,9 @@ HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_005, TestSize.Level1) */ HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_006, TestSize.Level1) { - std::string ret = appfreezeManager->CatcherStacktrace(0); + std::string ret = appfreezeManager->CatcherStacktrace(0, ""); printf("ret: %s\n", ret.c_str()); - ret = appfreezeManager->CatcherStacktrace(2); + ret = appfreezeManager->CatcherStacktrace(2, ""); printf("ret: %s\n", ret.c_str()); EXPECT_TRUE(!ret.empty()); appfreezeManager->ClearOldInfo(); @@ -269,5 +269,16 @@ HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_CatchStack_001, TestSize.Lev appfreezeManager->DeleteStack(pid); EXPECT_TRUE(appfreezeManager->catchStackMap_.empty()); } + +/** + * @tc.number: AppfreezeManagerTest_GetFormatTime_001 + * @tc.name: GetFormatTime + * @tc.desc: Verify that function GetFormatTime. + */ +HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_GetFormatTime_001, TestSize.Level1) +{ + std::string ret = appfreezeManager->GetFormatTime(); + EXPECT_TRUE(!ret.empty()); +} } // namespace AppExecFwk } // namespace OHOS