mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-24 22:21:36 -04:00
@@ -123,6 +123,7 @@ declare_args() {
|
||||
ability_runtime_media_library_enable = true
|
||||
ability_runtime_no_screen = false
|
||||
ability_runtime_hitrace_enable = true
|
||||
ability_runtime_hiperf_enable = true
|
||||
|
||||
if (!defined(global_parts_info) ||
|
||||
defined(global_parts_info.account_os_account)) {
|
||||
@@ -231,4 +232,9 @@ declare_args() {
|
||||
!defined(global_parts_info.hiviewdfx_hitrace)) {
|
||||
ability_runtime_hitrace_enable = false
|
||||
}
|
||||
|
||||
if (defined(global_parts_info) &&
|
||||
!defined(global_parts_info.developtools_hiperf)) {
|
||||
ability_runtime_hiperf_enable = false
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -111,7 +111,8 @@
|
||||
"udmf",
|
||||
"webview",
|
||||
"window_manager",
|
||||
"zlib"
|
||||
"zlib",
|
||||
"hiperf"
|
||||
],
|
||||
"third_party": [
|
||||
"libjpeg-turbo"
|
||||
|
||||
@@ -229,6 +229,18 @@ ohos_shared_library("appkit_native") {
|
||||
deps += [ "${ability_runtime_innerkits_path}/child_process_manager:child_process_manager" ]
|
||||
}
|
||||
|
||||
if (ability_runtime_hiperf_enable) {
|
||||
defines += [ "SUPPORT_HIPERF" ]
|
||||
sources += [
|
||||
"${ability_runtime_native_path}/appkit/dfr/appcapture_perf.cpp",
|
||||
]
|
||||
external_deps += [
|
||||
"hiperf:hiperf_local",
|
||||
"faultloggerd:libunwinder",
|
||||
"faultloggerd:libstack_printer",
|
||||
]
|
||||
}
|
||||
|
||||
if (ability_runtime_graphics) {
|
||||
external_deps += [
|
||||
"ace_engine:ace_forward_compatibility",
|
||||
|
||||
@@ -96,6 +96,9 @@
|
||||
#include "js_runtime_utils.h"
|
||||
#include "context/application_context.h"
|
||||
#include "os_account_manager_wrapper.h"
|
||||
#ifdef SUPPORT_HIPERF
|
||||
#include "appcapture_perf.h"
|
||||
#endif
|
||||
|
||||
#if defined(NWEB)
|
||||
#include <thread>
|
||||
@@ -3570,6 +3573,12 @@ int32_t MainThread::ScheduleNotifyAppFault(const FaultData &faultData)
|
||||
return AppExecFwk::AppfreezeInner::GetInstance()->AppfreezeHandle(faultData, false);
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_HIPERF
|
||||
if (faultData.faultType == FaultDataType::CPU_LOAD) {
|
||||
return AppExecFwk::AppCapturePerf::GetInstance()->CapturePerf(faultData);
|
||||
}
|
||||
#endif
|
||||
|
||||
wptr<MainThread> weak = this;
|
||||
auto task = [weak, faultData] {
|
||||
auto appThread = weak.promote();
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2025 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 "appcapture_perf.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "hisysevent.h"
|
||||
#include "lperf.h"
|
||||
#include "hilog_tag_wrapper.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AppExecFwk {
|
||||
const int32_t CAPTURE_DURATION = 1000;
|
||||
const int32_t FREQ = 100;
|
||||
|
||||
std::shared_ptr<AppCapturePerf> AppCapturePerf::instance_ = nullptr;
|
||||
std::mutex AppCapturePerf::singletonMutex_;
|
||||
|
||||
std::shared_ptr<AppCapturePerf> AppCapturePerf::GetInstance()
|
||||
{
|
||||
if (instance_ == nullptr) {
|
||||
std::lock_guard<std::mutex> lock(singletonMutex_);
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = std::make_shared<AppCapturePerf>();
|
||||
}
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
std::vector<std::string> AppCapturePerf::SplitStr(const std::string &s, char delimiter)
|
||||
{
|
||||
std::vector<std::string> tokens;
|
||||
std::string token;
|
||||
std::istringstream tokenStream(s);
|
||||
while (std::getline(tokenStream, token, delimiter)) {
|
||||
tokens.push_back(token);
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
int32_t AppCapturePerf::CapturePerf(const FaultData &faultData)
|
||||
{
|
||||
std::vector<int32_t> tids;
|
||||
std::vector<std::string> threads = SplitStr(faultData.errorObject.stack, ',');
|
||||
for (int32_t i = 0; i < threads.size(); i++) {
|
||||
if (threads[i] == "") {
|
||||
continue;
|
||||
}
|
||||
tids.push_back(stoi(threads[i]));
|
||||
}
|
||||
int res = -2;
|
||||
auto &instance = Developtools::HiPerf::HiPerfLocal::Lperf::GetInstance();
|
||||
res = instance.StartProcessStackSampling(tids, FREQ, CAPTURE_DURATION, false);
|
||||
if (res != 0) {
|
||||
TAG_LOGE(AAFwkTag::APPDFR, "hiperf stack capture failed");
|
||||
return 0;
|
||||
}
|
||||
std::vector<std::string> perf;
|
||||
for (int32_t i = 0; i < tids.size(); i++) {
|
||||
std::string stack;
|
||||
res = instance.CollectSampleStackByTid(tids[i], stack);
|
||||
if (res != 0) {
|
||||
perf.push_back("");
|
||||
continue;
|
||||
}
|
||||
perf.push_back(stack);
|
||||
}
|
||||
res = instance.FinishProcessStackSampling();
|
||||
if (res != 0) {
|
||||
TAG_LOGE(AAFwkTag::APPDFR, "hiperf stack clean failed");
|
||||
}
|
||||
int64_t perfId = std::strtoll(faultData.timeoutMarkers.c_str(), nullptr, 10);
|
||||
int ret = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::RELIABILITY, "CPU_LOAD_CAPTURE_STACK",
|
||||
HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_NAME", faultData.errorObject.name,
|
||||
"TIDS", tids, "PERF", perf, "PERFID", perfId);
|
||||
if (ret != 0) {
|
||||
TAG_LOGE(AAFwkTag::APPDFR, "HiSysEventWrite CPU_LOAD_CAPTURE_STACK failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AppCapturePerf::DestroyInstance()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(singletonMutex_);
|
||||
if (instance_ != nullptr) {
|
||||
instance_.reset();
|
||||
instance_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AppExecFwk
|
||||
} // namespace OHOS
|
||||
@@ -35,6 +35,7 @@ enum class FaultDataType {
|
||||
JS_ERROR,
|
||||
CJ_ERROR,
|
||||
APP_FREEZE,
|
||||
CPU_LOAD,
|
||||
PERFORMANCE_CONTROL,
|
||||
RESOURCE_CONTROL
|
||||
};
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2025 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_APP_CAPTURE_PERF_H
|
||||
#define OHOS_ABILITY_ABILITY_APP_CAPTURE_PERF_H
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include "fault_data.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AppExecFwk {
|
||||
class AppCapturePerf {
|
||||
public:
|
||||
AppCapturePerf() {}
|
||||
~AppCapturePerf() {}
|
||||
static std::shared_ptr<AppCapturePerf> GetInstance();
|
||||
static void DestroyInstance();
|
||||
int32_t CapturePerf(const FaultData &faultData);
|
||||
std::vector<std::string> SplitStr(const std::string &s, char delimiter);
|
||||
private:
|
||||
static std::shared_ptr<AppCapturePerf> instance_;
|
||||
static std::mutex singletonMutex_;
|
||||
};
|
||||
} // namespace AppExecFwk
|
||||
} // namespace OHOS
|
||||
#endif // OHOS_ABILITY_ABILITY_APP_CAPTURE_PERF_H
|
||||
@@ -23,5 +23,6 @@ group("unittest") {
|
||||
"cpu_data_processor_test:unittest",
|
||||
"dump_proc_helper_test:unittest",
|
||||
"watchdog_test:unittest",
|
||||
"appcapture_perf_test:unittest",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
# Copyright (c) 2025 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.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
import("//build/test.gni")
|
||||
import("//foundation/ability/ability_runtime/ability_runtime.gni")
|
||||
|
||||
module_output_path = "ability_runtime/freeze_checker"
|
||||
|
||||
###############################################################################
|
||||
config("module_context_config") {
|
||||
visibility = [ ":*" ]
|
||||
include_dirs = [
|
||||
"${ability_runtime_innerkits_path}/app_manager/include/appmgr",
|
||||
"${ability_runtime_test_path}/mock/frameworks_kits_appkit_native_test/include",
|
||||
"${ability_runtime_test_path}/mock/frameworks_kits_ability_native_test/include",
|
||||
"${ability_runtime_path}/interfaces/kits/native/appkit/app/task",
|
||||
"${ability_runtime_path}/interfaces/kits/native/ability/native",
|
||||
]
|
||||
cflags = []
|
||||
if (target_cpu == "arm") {
|
||||
cflags += [ "-DBINDER_IPC_32BIT" ]
|
||||
}
|
||||
defines = [ "AMS_LOG_TAG = \"ApplicationUnitTest\"" ]
|
||||
}
|
||||
|
||||
config("ability_start_setting_config") {
|
||||
visibility = [ ":*" ]
|
||||
include_dirs = [
|
||||
"${ability_runtime_path}/interfaces/kits/native/appkit/app",
|
||||
"${ability_runtime_path}/interfaces/kits/native/appkit/dfr",
|
||||
"${ability_runtime_innerkits_path}/ability_manager/include",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_unittest("appcapture_perf_test") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
include_dirs = [
|
||||
"${ability_runtime_path}/interfaces/kits/native/appkit/dfr",
|
||||
"${ability_runtime_path}/utils/global/time/include",
|
||||
]
|
||||
|
||||
configs = [
|
||||
":module_context_config",
|
||||
":ability_start_setting_config",
|
||||
]
|
||||
|
||||
sources = [
|
||||
"${ability_runtime_native_path}/appkit/dfr/appcapture_perf.cpp",
|
||||
"appcapture_perf_test.cpp",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"${ability_runtime_abilitymgr_path}/:abilityms",
|
||||
"${ability_runtime_innerkits_path}/ability_manager:ability_manager",
|
||||
"${ability_runtime_innerkits_path}/app_manager:app_manager",
|
||||
"${ability_runtime_innerkits_path}/deps_wrapper:ability_deps_wrapper",
|
||||
"${ability_runtime_innerkits_path}/runtime:runtime",
|
||||
"${ability_runtime_native_path}/ability/native:ability_thread",
|
||||
"${ability_runtime_native_path}/ability/native:abilitykit_native",
|
||||
"${ability_runtime_native_path}/ability/native:uiabilitykit_native",
|
||||
"${ability_runtime_native_path}/appkit:app_context",
|
||||
"${ability_runtime_native_path}/appkit:app_context_utils",
|
||||
"${ability_runtime_native_path}/appkit:appkit_native",
|
||||
"${ability_runtime_path}/js_environment/frameworks/js_environment:js_environment",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"ability_base:configuration",
|
||||
"ability_base:extractresourcemanager",
|
||||
"ability_base:string_utils",
|
||||
"ability_base:want",
|
||||
"bundle_framework:appexecfwk_base",
|
||||
"bundle_framework:appexecfwk_core",
|
||||
"c_utils:utils",
|
||||
"common_event_service:cesfwk_innerkits",
|
||||
"eventhandler:libeventhandler",
|
||||
"faultloggerd:libbacktrace_local",
|
||||
"faultloggerd:libdfx_procinfo",
|
||||
"faultloggerd:libfaultloggerd",
|
||||
"ffrt:libffrt",
|
||||
"googletest:gmock_main",
|
||||
"googletest:gtest_main",
|
||||
"graphic_2d:librender_service_client",
|
||||
"hicollie:libhicollie",
|
||||
"hilog:libhilog",
|
||||
"hisysevent:libhisysevent",
|
||||
"hitrace:hitrace_meter",
|
||||
"init:libbegetutil",
|
||||
"input:libmmi-client",
|
||||
"ipc:ipc_core",
|
||||
"json:nlohmann_json_static",
|
||||
"napi:ace_napi",
|
||||
"resource_management:global_resmgr",
|
||||
"safwk:system_ability_fwk",
|
||||
"samgr:samgr_proxy",
|
||||
"hiperf:hiperf_local",
|
||||
"faultloggerd:libunwinder",
|
||||
"faultloggerd:libstack_printer"
|
||||
]
|
||||
|
||||
if (ability_runtime_upms) {
|
||||
deps += [
|
||||
"${ability_runtime_innerkits_path}/uri_permission:uri_permission_mgr",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
group("unittest") {
|
||||
testonly = true
|
||||
deps = [ ":appcapture_perf_test" ]
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2025 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 <gtest/gtest.h>
|
||||
|
||||
#define private public
|
||||
#include "appcapture_perf.h"
|
||||
#undef private
|
||||
#include "cpp/mutex.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace testing::ext;
|
||||
using namespace OHOS;
|
||||
using namespace OHOS::AppExecFwk;
|
||||
|
||||
namespace OHOS {
|
||||
namespace AppExecFwk {
|
||||
class AppCapturePerfTest : public testing::Test {
|
||||
public:
|
||||
AppCapturePerfTest()
|
||||
{}
|
||||
~AppCapturePerfTest()
|
||||
{}
|
||||
std::shared_ptr<AppCapturePerf> appCapturePerf = nullptr;
|
||||
static void SetUpTestCase(void);
|
||||
static void TearDownTestCase(void);
|
||||
void SetUp();
|
||||
void TearDown();
|
||||
};
|
||||
|
||||
void AppCapturePerfTest::SetUpTestCase(void)
|
||||
{}
|
||||
|
||||
void AppCapturePerfTest::TearDownTestCase(void)
|
||||
{}
|
||||
|
||||
void AppCapturePerfTest::SetUp(void)
|
||||
{
|
||||
appCapturePerf = AppCapturePerf::GetInstance();
|
||||
}
|
||||
|
||||
void AppCapturePerfTest::TearDown(void)
|
||||
{
|
||||
AppCapturePerf::DestroyInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AppCapturePerfTest001
|
||||
* @tc.desc: add testcase codecoverage
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(AppCapturePerfTest, AppCapturePerfTest001, TestSize.Level0)
|
||||
{
|
||||
ASSERT_TRUE(appCapturePerf != nullptr);
|
||||
GTEST_LOG_(INFO) << "test AppCapturePerfTest001 Data.\n";
|
||||
FaultData faultData;
|
||||
faultData.errorObject.name = "testapp";
|
||||
faultData.errorObject.message = "test";
|
||||
faultData.errorObject.stack = "";
|
||||
int32_t ret = appCapturePerf->CapturePerf(faultData);
|
||||
EXPECT_EQ(ret, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AppCapturePerfTest002
|
||||
* @tc.desc: add testcase codecoverage
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(AppCapturePerfTest, AppCapturePerfTest002, TestSize.Level0)
|
||||
{
|
||||
ASSERT_TRUE(appCapturePerf != nullptr);
|
||||
GTEST_LOG_(INFO) << "test AppCapturePerfTest002 Data.\n";
|
||||
FaultData faultData;
|
||||
faultData.errorObject.name = "testapp";
|
||||
faultData.errorObject.message = "test";
|
||||
faultData.errorObject.stack = "123,,1478";
|
||||
int32_t ret = appCapturePerf->CapturePerf(faultData);
|
||||
EXPECT_EQ(ret, 0);
|
||||
}
|
||||
} // namespace AppExecFwk
|
||||
} // namespace OHOS
|
||||
Reference in New Issue
Block a user