Merge branch 'master' of gitee.com:openharmony/developtools_profiler into master

Signed-off-by: wenlong_12 <wenlong12@huawei.com>
This commit is contained in:
wenlong_12 2023-10-08 09:47:37 +00:00
commit be16c260be
61 changed files with 450 additions and 240 deletions

View File

@ -44,14 +44,14 @@
],
"third_party": [
"bounds_checking_function",
"cJSON",
"googletest",
"grpc",
"libbpf",
"libunwind",
"openssl",
"protobuf",
"zlib",
"cJSON"
"zlib"
]
},
"build": {

View File

@ -16,6 +16,7 @@ import("../../build/config.gni")
build_tests = false
enable_debuginfo = false
enable_coverage = false
hiprofiler_fuzz_output_path = "hiprofiler/hiprofiler"
if (getenv("BUILD_UT") == "true") {
build_tests = true

View File

@ -15,17 +15,19 @@
#ifndef COMMON_H
#define COMMON_H
#include <malloc.h>
#include <string>
#include <vector>
#include <sys/types.h>
#include <unistd.h>
namespace COMMON {
bool IsProcessRunning(int& lockFileFd); // add file lock, only one process can run
bool IsProcessExist(const std::string& processName, int& pid); // Check if the process exists and get PID
int StartProcess(const std::string& processBin, std::vector<char*>& argv);
int KillProcess(int pid);
void PrintMallinfoLog(const std::string& mallInfoPrefix);
void PrintMallinfoLog(const std::string& mallInfoPrefix, const struct mallinfo2& mi);
inline int CustomFdClose(int& fd);
inline int CustomFdFclose(FILE** fp);
FILE* CustomPopen(const std::vector<std::string>& command, const char* type, int fds[],

View File

@ -21,9 +21,6 @@
#include <dirent.h>
#include <fstream>
#include <iostream>
#ifdef HOOK_ENABLE
#include <malloc.h>
#endif
#include <sstream>
#include <sys/file.h>
#include <sys/types.h>
@ -51,7 +48,7 @@ constexpr int WRITE = 1;
const int FILE_PATH_SIZE = 512;
const int BUFFER_SIZE = 1024;
const int INVALID_PID = -1;
const int32_t EC_INVALID_VALUE = -2;
constexpr int32_t EC_INVALID_VALUE = -2;
bool IsProcessRunning(int& lockFileFd)
@ -191,18 +188,17 @@ int KillProcess(int pid)
return stat;
}
void PrintMallinfoLog(const std::string& mallInfoPrefix)
void PrintMallinfoLog(const std::string& mallInfoPrefix, const struct mallinfo2& mi)
{
#ifdef HOOK_ENABLE
struct mallinfo2 mallinfo = mallinfo2();
std::string mallinfoLog = mallInfoPrefix;
mallinfoLog += "arena = " + std::to_string(mallinfo.arena) + ", ordblks = " + std::to_string(mallinfo.ordblks);
mallinfoLog += ", smblks = " + std::to_string(mallinfo.smblks) + ", hblks = " + std::to_string(mallinfo.hblks);
mallinfoLog += ", hblkhd = " + std::to_string(mallinfo.hblkhd) + ", usmblks = " + std::to_string(mallinfo.usmblks);
mallinfoLog += "arena = " + std::to_string(mi.arena) + ", ordblks = " + std::to_string(mi.ordblks);
mallinfoLog += ", smblks = " + std::to_string(mi.smblks) + ", hblks = " + std::to_string(mi.hblks);
mallinfoLog += ", hblkhd = " + std::to_string(mi.hblkhd) + ", usmblks = " + std::to_string(mi.usmblks);
mallinfoLog +=
", fsmblks = " + std::to_string(mallinfo.fsmblks) + ", uordblks = " + std::to_string(mallinfo.uordblks);
", fsmblks = " + std::to_string(mi.fsmblks) + ", uordblks = " + std::to_string(mi.uordblks);
mallinfoLog +=
", fordblks = " + std::to_string(mallinfo.fordblks) + ", keepcost = " + std::to_string(mallinfo.keepcost);
", fordblks = " + std::to_string(mi.fordblks) + ", keepcost = " + std::to_string(mi.keepcost);
HILOG_INFO(LOG_CORE, "%s", mallinfoLog.c_str());
#endif // HOOK_ENABLE
}

View File

@ -15,6 +15,8 @@
#include <arpa/inet.h>
#include <cinttypes>
#include <condition_variable>
#include <csignal>
#include <cstdio>
#include <cstring>
#include <fstream>
@ -53,6 +55,9 @@ uint32_t g_sampleDuration = 0;
int g_hiprofilerdPid = -1;
int g_hiprofilerPluginsPid = -1;
int g_nativeDaemonPid = -1;
std::condition_variable g_sessionCv;
std::condition_variable g_keepSessionCv;
bool g_exitProcessFlag = false;
std::string GetLoopbackAddress()
{
@ -241,6 +246,7 @@ bool CheckStopSession(std::unique_ptr<IProfilerService::Stub>& profilerStub, uin
return false;
}
printf("StopSession done!\n");
return true;
}
@ -255,15 +261,46 @@ bool CheckDestroySession(std::unique_ptr<IProfilerService::Stub>& profilerStub,
return false;
}
printf("DestroySession done!\n");
return true;
}
void StartKeepAliveThread(std::unique_ptr<IProfilerService::Stub> &profilerStub,
uint32_t &id, std::atomic<bool> &sendHeart)
{
while (sendHeart.load()) {
KeepSessionRequest keepRequest;
keepRequest.set_request_id(0);
keepRequest.set_session_id(id);
keepRequest.set_keep_alive_time(KEEP_SESSION_TIMEOUT_MS);
grpc::ClientContext keepContext;
KeepSessionResponse keepResponse;
profilerStub->KeepSession(&keepContext, keepRequest, &keepResponse);
std::mutex keepSessionMutex;
std::unique_lock<std::mutex> lck(keepSessionMutex);
g_keepSessionCv.wait_for(lck, std::chrono::seconds(KEEP_SESSION_SLEEP_SECOND));
}
}
void StopKeepAliveThread(std::thread& keepSessionThread, std::atomic<bool>& sendHeart)
{
sendHeart = false;
g_keepSessionCv.notify_one();
if (keepSessionThread.joinable()) {
keepSessionThread.join();
}
}
bool DoCapture(const std::string& config, const std::string& keepSecond, const std::string& outputFile)
{
auto profilerStub = GetProfilerServiceStub();
if (profilerStub == nullptr) {
printf("Get profiler service stub failed!\n");
return 0;
return false;
}
if (g_exitProcessFlag) {
return false;
}
uint32_t sessionId = CreateSession(profilerStub, config, keepSecond, outputFile);
@ -271,46 +308,41 @@ bool DoCapture(const std::string& config, const std::string& keepSecond, const s
printf("Create session returns Id 0\n");
return false;
}
if (g_exitProcessFlag) {
// session has been created, need to destroy the session.
return CheckDestroySession(profilerStub, sessionId);
}
// 开启心跳线程确保会话正常睡眠3s下发一次5s超时心跳
bool sendHeart = true;
std::thread keepSessionThread([&]() {
while (sendHeart) {
KeepSessionRequest keepRequest;
keepRequest.set_request_id(0);
keepRequest.set_session_id(sessionId);
keepRequest.set_keep_alive_time(KEEP_SESSION_TIMEOUT_MS);
grpc::ClientContext keepContext;
KeepSessionResponse keepResponse;
profilerStub->KeepSession(&keepContext, keepRequest, &keepResponse);
std::this_thread::sleep_for(std::chrono::seconds(KEEP_SESSION_SLEEP_SECOND));
}
});
// start keepSessionThread, in order to ensure the sessionId is valid.
std::atomic<bool> sendHeart = true;
std::thread keepSessionThread(StartKeepAliveThread, std::ref(profilerStub),
std::ref(sessionId), std::ref(sendHeart));
if (g_exitProcessFlag) {
// session has been created and keepSessionThread has been started.
// need to stop keepSessionThread and destroy the session.
StopKeepAliveThread(keepSessionThread, sendHeart);
return CheckDestroySession(profilerStub, sessionId);
}
if (!CheckStartSession(profilerStub, sessionId)) {
return false;
}
printf("tracing %u ms....\n", g_sampleDuration);
std::this_thread::sleep_for(std::chrono::milliseconds(g_sampleDuration));
if (!CheckStopSession(profilerStub, sessionId)) {
sendHeart = false;
keepSessionThread.join();
return false;
if (!g_exitProcessFlag) {
// waiting for the collection time to end or signal wakeup.
printf("tracing %u ms....\n", g_sampleDuration);
std::mutex sessionMutex;
std::unique_lock<std::mutex> lck(sessionMutex);
g_sessionCv.wait_for(lck, std::chrono::milliseconds(g_sampleDuration));
}
printf("StopSession done!\n");
if (!CheckDestroySession(profilerStub, sessionId)) {
sendHeart = false;
keepSessionThread.join();
return false;
bool ret = false;
if (CheckStopSession(profilerStub, sessionId) && CheckDestroySession(profilerStub, sessionId)) {
ret = true;
}
printf("DestroySession done!\n");
sendHeart = false;
keepSessionThread.join();
return true;
StopKeepAliveThread(keepSessionThread, sendHeart);
return ret;
}
struct DataContext {
@ -459,10 +491,21 @@ bool ParseConfig(const std::string& configFile, std::string& config)
}
return true;
}
void SignalHandler(int signal)
{
printf("hiprofiler_cmd receive signal(%d)!\n", signal);
if (signal == SIGINT) {
g_exitProcessFlag = true;
g_sessionCv.notify_one();
}
}
} // namespace
int main(int argc, char* argv[])
{
signal(SIGINT, SignalHandler);
std::string config = "";
while (true) {
struct option long_options[] = {
@ -512,6 +555,9 @@ int main(int argc, char* argv[])
exit(0);
}
// need to delete old file.
remove(data.outputFile.c_str());
if (config.empty() && !data.configFile.empty()) {
if (!ParseConfig(data.configFile, config)) {
return -1;

View File

@ -426,7 +426,7 @@ HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0130, Function | MediumTest | Lev
}
/**
* @tc.name: native hook
* @tc.name: hiprofiler_cmd
* @tc.desc: Test hiprofiler_cmd with -s -l -k.
* @tc.type: FUNC
*/
@ -443,7 +443,7 @@ HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0140, Function | MediumTest | Lev
}
/**
* @tc.name: native hook
* @tc.name: hiprofiler_cmd
* @tc.desc: Test hiprofiler_cmd with -l -k.
* @tc.type: FUNC
*/
@ -458,7 +458,7 @@ HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0150, Function | MediumTest | Lev
}
/**
* @tc.name: native hook
* @tc.name: hiprofiler_cmd
* @tc.desc: Test hiprofiler_cmd with -k.
* @tc.type: FUNC
*/
@ -501,4 +501,56 @@ HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0170, Function | MediumTest | Lev
StopProcessStub(hiprofilerPluginsPid_);
StopProcessStub(hiprofilerdPid_);
}
/**
* @tc.name: hiprofiler_cmd
* @tc.desc: Test hiprofiler_cmd with ctrl+c.
* @tc.type: FUNC
*/
HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0180, Function | MediumTest | Level1)
{
std::string content = "";
std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -s";
EXPECT_TRUE(RunCommand(cmd, content));
sleep(1);
pid_t pid = fork();
EXPECT_GE(pid, 0);
if (pid == 0) {
content = "";
const int time = 20;
std::string outFile = DEFAULT_PATH + "trace.htrace";
cmd = CreateCommand(outFile, time);
EXPECT_TRUE(RunCommand(cmd, content));
EXPECT_TRUE(content.find("hiprofiler_cmd receive signal(2)!", 0) != std::string::npos);
EXPECT_EQ(access(outFile.c_str(), F_OK), 0);
// 删除生成的trace文件
cmd = "rm " + outFile;
system(cmd.c_str());
_exit(0);
} else if (pid > 0) {
sleep(10);
content = "";
cmd = "pidof hiprofiler_cmd";
EXPECT_TRUE(RunCommand(cmd, content));
ASSERT_STRNE(content.c_str(), "");
cmd = "kill -2 " + content;
content = "";
EXPECT_TRUE(RunCommand(cmd, content));
EXPECT_STREQ(content.c_str(), "");
// 等待子进程结束
waitpid(pid, nullptr, 0);
}
cmd = DEFAULT_HIPROFILER_CMD_PATH + " -k";
EXPECT_TRUE(RunCommand(cmd, content));
sleep(1);
content = "";
cmd = "pidof " + DEFAULT_HIPROFILERD_NAME;
EXPECT_TRUE(RunCommand(cmd, content));
EXPECT_STREQ(content.c_str(), "");
}
}

View File

@ -159,10 +159,10 @@
<preparer>
<option name="push" value="plugins/arkts_plugin/test/resources/entry-default-signed.hap -> /data/local/tmp/" src="res"/>
<option name="shell" value="bm install -r -p /data/local/tmp/entry-default-signed.hap"/>
<option name="shell" value="aa start -a MainAbility -b com.ohos.distributedmusicplayer"/>
<option name="shell" value="aa start -a EntryAbility -b cn.openharmony.rebound_project"/>
</preparer>
<cleaner>
<option name="uninstall" value="com.ohos.distributedmusicplayer"/>
<option name="uninstall" value="cn.openharmony.rebound_project"/>
</cleaner>
</target>
<target name="ftrace_plugin_ut">
@ -175,4 +175,12 @@
<option name="push" value="plugins/ftrace_plugin/test/unittest/resource/test_comm -> /data/local/tmp/" src="res"/>
</preparer>
</target>
<target name="xpowerplugin_ut">
<preparer>
<option name="shell" value="aa start -a EntryAbility -b com.taobao.taobao"/>
</preparer>
<cleaner>
<option name="shell" value="aa force-stop com.taobao.taobao"/>
</cleaner>
</target>
</configuration>

View File

@ -409,7 +409,7 @@ bool PluginManager::PullResult(uint32_t pluginId, bool isProtobufSerialize)
pluginModules_[pluginId]->GetPluginVersion(version);
if (isProtobufSerialize) {
std::unique_ptr<uint8_t[]> buffer(new (std::nothrow) uint8_t[size]);
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
CHECK_NOTNULL(buffer, false, "%s:buffer new failed!", __func__);
int length = it->second->ReportResult(buffer.get(), size);

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
##############################fuzztest##########################################
ohos_fuzztest("PluginCreateSessionCmdFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/plugins/api/test/fuzztest/plugincreatesessioncmd_fuzzer"
include_dirs = []
cflags = [

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
##############################fuzztest##########################################
ohos_fuzztest("PluginDestroySessionCmdFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/plugins/api/test/fuzztest/plugindestroysessioncmd_fuzzer"
include_dirs = []
cflags = [

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
##############################fuzztest##########################################
ohos_fuzztest("PluginStartSessionCmdFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/plugins/api/test/fuzztest/pluginstartsessioncmd_fuzzer"
include_dirs = []
cflags = [

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
##############################fuzztest##########################################
ohos_fuzztest("PluginStopSessionCmdFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/plugins/api/test/fuzztest/pluginstopsessioncmd_fuzzer"
include_dirs = []
cflags = [

Binary file not shown.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* 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
@ -28,6 +28,8 @@
#include "plugin_module_api.h"
using namespace testing::ext;
namespace {
class ArkTSPluginTest : public ::testing::Test {
public:
ArkTSPluginTest()
@ -42,7 +44,7 @@ public:
std::array<char, readBufferSize> buffer;
while (fgets(buffer.data(), buffer.size(), runCmd.get()) != nullptr) {
std::string result = buffer.data();
if (result.find("com.ohos.dist") == std::string::npos) {
if (result.find("cn.openharmony") == std::string::npos) {
continue;
}
std::regex pattern(R"(\b(\d+)/)");
@ -63,8 +65,10 @@ public:
int32_t pid_{0};
};
std::vector<uint8_t> SetArkTSConfig(ArkTSConfig& protoConfig, int32_t pid, ArkTSConfig::HeapType type, uint32_t interval, bool capture_numeric_value,
bool track_allocations, bool enable_cpu_profiler, uint32_t cpu_profiler_interval = 1000)
std::vector<uint8_t> SetArkTSConfig(
ArkTSConfig &protoConfig, int32_t pid, ArkTSConfig::HeapType type,
uint32_t interval, bool capture_numeric_value, bool track_allocations,
bool enable_cpu_profiler, uint32_t cpu_profiler_interval = 1000)
{
protoConfig.set_pid(pid);
protoConfig.set_type(type);
@ -173,4 +177,5 @@ HWTEST_F(ArkTSPluginTest, TestCpuProfiler, TestSize.Level1)
EXPECT_EQ(arkTSPlugin.Start(configData.data(), configData.size()), 0);
sleep(5);
EXPECT_EQ(arkTSPlugin.Stop(), 0);
}
}
} // namespace

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
##############################fuzztest##########################################
ohos_fuzztest("CpuStartPluginFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/plugins/cpu_plugin/test/fuzztest/cpustartplugin_fuzzer"
cflags = [
"-g",

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
##############################fuzztest##########################################
ohos_fuzztest("DiskioStartPluginFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/plugins/diskio_plugin/test/fuzztest/diskiostartplugin_fuzzer"
cflags = [
"-g",

View File

@ -24,7 +24,6 @@
#include "trace_plugin_result.pbencoder.h"
FTRACE_NS_BEGIN
using namespace OHOS::Developtools::Profiler;
template <class T> // T: FtraceEvent
class SubEventParser {
@ -156,14 +155,15 @@ private:
class SubEventParserOptimizeRegisterar {
public:
SubEventParserOptimizeRegisterar(const std::string& name,
SubEventParser<ProtoEncoder::FtraceEvent>::ParseFunction&& func)
SubEventParser<Developtools::Profiler::ProtoEncoder::FtraceEvent>::ParseFunction&& func)
{
SubEventParser<ProtoEncoder::FtraceEvent>::GetInstance().RegisterParseFunction(name, std::move(func));
SubEventParser<Developtools::Profiler::ProtoEncoder::FtraceEvent>::GetInstance().RegisterParseFunction(name,
std::move(func));
name_ = name;
}
~SubEventParserOptimizeRegisterar()
{
SubEventParser<ProtoEncoder::FtraceEvent>::GetInstance().UnregisterParseFunction(name_);
SubEventParser<Developtools::Profiler::ProtoEncoder::FtraceEvent>::GetInstance().UnregisterParseFunction(name_);
}
private:

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
##############################fuzztest##########################################
ohos_fuzztest("HidumpStartPluginFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/plugins/hidump_plugin/test/fuzztest/hidumpstartplugin_fuzzer"
cflags = [
"-g",

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
##############################fuzztest##########################################
ohos_fuzztest("HilogStartPluginFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/plugins/hilog_plugin/test/fuzztest/hilogstartplugin_fuzzer"
cflags = [
"-g",

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
##############################fuzztest##########################################
ohos_fuzztest("HiperfStartPluginFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/plugins/hiperf_plugin/test/fuzztest/hiperfstartplugin_fuzzer"
cflags = [
"-g",

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
##############################fuzztest##########################################
ohos_fuzztest("MemoryStartPluginFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/plugins/memory_plugin/test/fuzztest/memorystartplugin_fuzzer"
cflags = [
"-g",

View File

@ -27,6 +27,9 @@ config("hook_config") {
"NATIVEDAEMON_USE_CALLSTACK",
]
defines += [ "target_cpu_${target_cpu}" ]
if (use_jemalloc) {
defines += [ "USE_JEMALLOC" ]
}
}
ohos_prebuilt_etc("hiprofiler_daemon.cfg") {

View File

@ -103,6 +103,9 @@ private:
BatchNativeHookData& batchNativeHookData);
bool SetFreeStatisticsData(uint64_t addr);
void SetAllocStatisticsData(const RawStackPtr& rawStack, size_t stackId, bool isExists = false);
unsigned LgFloor(unsigned long x);
uint64_t PowCeil(uint64_t x);
size_t ComputeAlign(size_t size);
private:
std::shared_ptr<BufferWriter> writer_ = nullptr;
StackDataRepeaterPtr dataRepeater_ = nullptr;

View File

@ -391,7 +391,6 @@ bool HookManager::StopPluginSession(const std::vector<uint32_t>& pluginIds)
CHECK_TRUE(stackPreprocess_ != nullptr, false, "stop StackPreprocess FAIL");
HILOG_INFO(LOG_CORE, "start StopTakeResults");
stackPreprocess_->StopTakeResults();
HILOG_INFO(LOG_CORE, "StopTakeResults success");
if (hookConfig_.statistics_interval() > 0) {
stackPreprocess_->FlushRecordStatistics();

View File

@ -60,6 +60,7 @@ static void SignalHandl(int signo)
{
HILOG_ERROR(LOG_CORE, "recv signal %d", signo);
g_stackpreprocess->StopTakeResults();
if (g_statisticsinterval > 0) {
g_stackpreprocess->FlushRecordStatistics();
}
@ -170,4 +171,4 @@ bool StartHook(HookData& hookData)
} // namespace Hook
} // namespace Profiler
} // namespace Developtools
} // namespace OHOS
} // namespace OHOS

View File

@ -25,9 +25,18 @@
#include "native_hook_result_standard.pb.h"
#include "native_hook_config_standard.pb.h"
#include "google/protobuf/text_format.h"
static std::atomic<uint64_t> timeCost = 0;
static std::atomic<uint64_t> unwindTimes = 0;
constexpr static uint32_t SC_LG_TINY_MIN = 3;
constexpr static uint32_t LG_QUANTUM = 4;
constexpr static uint32_t SC_NTINY = LG_QUANTUM - SC_LG_TINY_MIN;
constexpr static uint32_t SC_LG_TINY_MAXCLASS = (LG_QUANTUM > SC_LG_TINY_MIN ? LG_QUANTUM - 1 : -1);
constexpr static uint32_t SC_LG_NGROUP = 2;
constexpr static uint32_t LG_SIZE_CLASS_GROUP = 2;
constexpr static uint32_t NTBINS = 1;
constexpr static uint32_t LG_TINY_MAXCLASS = 3;
constexpr static uint32_t MAX_BUFFER_SIZE = 10 * 1024 * 1024;
constexpr static uint32_t MAX_MATCH_CNT = 1000;
constexpr static uint32_t MAX_MATCH_INTERVAL = 2000;
@ -469,7 +478,11 @@ void StackPreprocess::SetHookData(RawStackPtr rawStack,
if (rawStack->stackConext->type == MALLOC_MSG) {
AllocEvent* allocEvent = hookData->mutable_alloc_event();
#ifdef USE_JEMALLOC
allocEvent->set_size(static_cast<uint64_t>(ComputeAlign(rawStack->stackConext->mallocSize)));
#else
allocEvent->set_size(static_cast<uint64_t>(rawStack->stackConext->mallocSize));
#endif
allocEvent->set_thread_name_id(rawStack->stackConext->tid);
SetEventFrame(rawStack, callFrames, batchNativeHookData, allocEvent, stackMapId);
} else if (rawStack->stackConext->type == FREE_MSG) {
@ -875,3 +888,67 @@ bool StackPreprocess::GetMemTag(uint32_t tagId, std::string& tagName)
{
return memTagMap_.Find(tagId, tagName);
}
unsigned StackPreprocess::LgFloor(unsigned long val)
{
val |= (val >> 1);
val |= (val >> 2);
val |= (val >> 4);
val |= (val >> 8);
val |= (val >> 16);
if (sizeof(val) > 4) {
int constant = sizeof(val) * 4;
val |= (val >> constant);
}
val++;
if (val == 0) {
return 8 * sizeof(val) - 1;
}
return __builtin_ffsl(val) - 2;
}
uint64_t StackPreprocess::PowCeil(uint64_t val)
{
++val;
val |= val >> 1;
val |= val >> 2;
val |= val >> 4;
val |= val >> 8;
val |= val >> 16;
val |= val >> 32;
++val;
return val;
}
size_t StackPreprocess::ComputeAlign(size_t size)
{
if (size == 0) {
return 0;
}
if (size <= (size_t(1) << SC_LG_TINY_MAXCLASS)) {
unsigned lgTmin = SC_LG_TINY_MAXCLASS - SC_NTINY + 1;
unsigned lgCeil = LgFloor(PowCeil(size));
return (lgCeil < lgTmin ? 0 : lgCeil - lgTmin);
}
unsigned floor = LgFloor((size << 1) - 1);
unsigned shift = (floor < SC_LG_NGROUP + LG_QUANTUM) ? 0 : floor - (SC_LG_NGROUP + LG_QUANTUM);
unsigned grp = shift << SC_LG_NGROUP;
unsigned lgDelta = (floor < SC_LG_NGROUP + LG_QUANTUM + 1) ? LG_QUANTUM : floor - SC_LG_NGROUP - 1;
size_t deltaInverseMask = size_t(-1) << lgDelta;
unsigned mod = ((((size - 1) & deltaInverseMask) >> lgDelta)) & ((size_t(1) << SC_LG_NGROUP) - 1);
unsigned index = SC_NTINY + grp + mod;
if (index < NTBINS) {
return (size_t(1) << (LG_TINY_MAXCLASS - NTBINS + 1 + index));
}
size_t reducedIndex = index - NTBINS;
size_t grpVal = reducedIndex >> LG_SIZE_CLASS_GROUP;
size_t modVal = reducedIndex & ((size_t(1) << LG_SIZE_CLASS_GROUP) - 1);
size_t grpSizeMask = ~((!!grpVal) - 1);
size_t grpSize = ((size_t(1) << (LG_QUANTUM + (LG_SIZE_CLASS_GROUP - 1))) << grpVal) & grpSizeMask;
size_t shiftVal = (grpVal == 0) ? 1 : grpVal;
size_t lgDeltaVal = shiftVal + (LG_QUANTUM - 1);
size_t modSize = (modVal + 1) << lgDeltaVal;
size_t usize = grpSize + modSize;
return usize;
}

View File

@ -17,6 +17,7 @@
#include <climits>
#include <dlfcn.h>
#include <fcntl.h>
#include <malloc.h>
#include <string>
#include <sys/time.h>
#include <pthread.h>
@ -59,6 +60,7 @@ constexpr int STATUS_LINE_SIZE = 512;
constexpr int PID_NAMESPACE_ID = 1; // 1: pid is 1 after pid namespace used
constexpr int FD_PATH_LENGTH = 64;
static bool g_isPidChanged = false;
static struct mallinfo2 g_miStart = {0};
const MallocDispatchType* GetDispatch()
{
return g_dispatch.load(std::memory_order_relaxed);
@ -176,7 +178,8 @@ static bool IsPidChanged(void);
bool ohos_malloc_hook_on_start(void)
{
std::lock_guard<std::recursive_timed_mutex> guard(g_ClientMutex);
COMMON::PrintMallinfoLog("before hook(byte) => ");
g_miStart = mallinfo2();
COMMON::PrintMallinfoLog("before hook(byte) => ", g_miStart);
g_hookPid = GetRealPid();
g_mallocTimes = 0;
if (g_hookClient != nullptr) {
@ -219,7 +222,9 @@ void* ohos_release_on_end(void*)
pthread_key_delete(g_updateThreadNameCount);
g_ClientConfig.Reset();
HILOG_INFO(LOG_CORE, "ohos_malloc_hook_on_end, mallocTimes :%" PRIu64, g_mallocTimes.load());
COMMON::PrintMallinfoLog("after hook(byte) => ");
COMMON::PrintMallinfoLog("before hook(byte) => ", g_miStart);
struct mallinfo2 miFinal = mallinfo2();
COMMON::PrintMallinfoLog("after hook(byte) => ", miFinal);
return nullptr;
}

View File

@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <malloc.h>
#include "hook_socket_client.h"
#include "common.h"
@ -75,8 +75,8 @@ bool HookSocketClient::ProtocolProc(SocketContext &context, uint32_t pnum, const
eventFd_ = context.ReceiveFileDiscriptor();
stackWriter_ = std::make_shared<StackWriter>("hooknativesmb", config_->shareMemroySize,
smbFd_, eventFd_, config_->isBlocked);
COMMON::PrintMallinfoLog("stackWriter init(byte) => ");
struct mallinfo2 mi = mallinfo2();
COMMON::PrintMallinfoLog("stackWriter init(byte) => ", mi);
return true;
}
@ -117,4 +117,4 @@ void HookSocketClient::Flush()
return;
}
stackWriter_->Flush();
}
}

View File

@ -34,7 +34,6 @@ constexpr int DEFAULT_MALLOC_SIZE = 10;
constexpr int DEFAULT_CALLOC_SIZE = 100;
constexpr int DEFAULT_REALLOC_SIZE = 1000;
constexpr int DATA_SIZE = 50;
constexpr int WAIT_KILL_SIGNL = 4;
constexpr int SLEEP_TIME = 5;
constexpr int WAIT_FLUSH = 2;
@ -301,12 +300,11 @@ public:
{
int processNum = fork();
if (processNum == 0) {
sleep(WAIT_KILL_SIGNL);
auto ret = malloc(DEFAULT_MALLOC_SIZE);
free(ret);
while (1) {
ApplyForCalloc(depth);
usleep(5000); // sleep 5000 us
usleep(500); // sleep 500 us
}
} else {
hookPid_ = processNum;
@ -388,11 +386,15 @@ public:
sleep(SLEEP_TIME); // 等待生成文本
std::string cmdEnd = "kill -37 " + std::to_string(hookPid_);
system(cmdEnd.c_str());
#ifdef COVERAGE_TEST
const int waitFlushTime = 5; // sleep 5s
sleep(waitFlushTime);
#else
sleep(WAIT_FLUSH);
#endif
StopProcess(hookPid_);
StopProcess(daemonPid_);
}
int daemonPid_ = -1;
int hookPid_ = -1;
int modeIndex_ = 0;

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
##############################fuzztest##########################################
ohos_fuzztest("NetworkStartPluginFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/plugins/network_plugin/test/fuzztest/networkstartplugin_fuzzer"
cflags = [
"-g",

View File

@ -23,6 +23,7 @@ namespace {
using namespace OHOS::Developtools::Profiler;
constexpr int MAX_INT = 10;
constexpr int MAX_DOUBLE = 100;
constexpr int CONST_NUMBER = 1024;
} // namespace
SamplePlugin::SamplePlugin() {}
@ -59,10 +60,8 @@ int SamplePlugin::ReportOptimize(RandomWriteCtx* randomWrite)
ProtoEncoder::SampleData dataProto(randomWrite);
// 回填数据
std::srand(std::time(nullptr));
int intRand = std::rand();
int intData = intRand % MAX_INT;
double doubleData = intRand % MAX_DOUBLE;
int intData = CONST_NUMBER % MAX_INT;
double doubleData = CONST_NUMBER % MAX_DOUBLE;
dataProto.set_time_ms(GetTimeMS());
dataProto.set_int_data(intData);
dataProto.set_double_data(doubleData);
@ -76,10 +75,8 @@ int SamplePlugin::Report(uint8_t* data, uint32_t dataSize)
SampleData dataProto;
// 回填数据
std::srand(std::time(nullptr));
int intRand = std::rand();
int intData = intRand % MAX_INT;
double doubleData = intRand % MAX_DOUBLE;
int intData = CONST_NUMBER % MAX_INT;
double doubleData = CONST_NUMBER % MAX_DOUBLE;
dataProto.set_time_ms(GetTimeMS());
dataProto.set_int_data(intData);
dataProto.set_double_data(doubleData);

View File

@ -1,4 +1,4 @@
# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
# Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
# 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* 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
@ -35,14 +35,14 @@ public:
void SetWriter(WriterStruct* writer);
bool StartPowerManager(std::uint32_t messageType, std::string& bundleName);
private:
void* powerClientHandle = nullptr;
XpowerConfig protoConfig;
MesTypeMap procMesTypeMapping;
std::shared_ptr<PowerMessageQueue> dataQueuePtr;
WriterStruct* resultWriter{nullptr};
void* powerClientHandle_ = nullptr;
XpowerConfig protoConfig_;
MesTypeMap procMesTypeMapping_;
std::shared_ptr<PowerMessageQueue> dataQueuePtr_;
WriterStruct* resultWriter_{nullptr};
// xpower callback config
OptimizeConfig config;
void* listenerHandle = nullptr;
OptimizeConfig config_;
void* listenerHandle_ = nullptr;
};
#endif // POWER_PLUGIN_H

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* 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
@ -26,16 +26,16 @@
namespace {
constexpr size_t MAX_QUEUE_SIZE = 2000;
uint32_t g_waitDuration = 100;
constexpr uint32_t WAIT_DURATION = 100;
constexpr int MIN_USER_ID = 10000;
} // namespace
XpowerPlugin::XpowerPlugin()
{
procMesTypeMapping.insert({XpowerMessageType::REAL_BATTERY, OptimizeMessageType::MESSAGE_REAL_BATTERY});
procMesTypeMapping.insert({XpowerMessageType::APP_STATISTIC, OptimizeMessageType::MESSAGE_APP_STATISTIC});
procMesTypeMapping.insert({XpowerMessageType::APP_DETAIL, OptimizeMessageType::MESSAGE_APP_DETAIL});
procMesTypeMapping.insert({XpowerMessageType::COMPONENT_TOP, OptimizeMessageType::MESSAGE_COMPONENT_TOP});
procMesTypeMapping.insert({XpowerMessageType::ABNORMAL_EVENTS, OptimizeMessageType::MESSAGE_ABNORMAL_EVENTS});
procMesTypeMapping_.insert({XpowerMessageType::REAL_BATTERY, OptimizeMessageType::MESSAGE_REAL_BATTERY});
procMesTypeMapping_.insert({XpowerMessageType::APP_STATISTIC, OptimizeMessageType::MESSAGE_APP_STATISTIC});
procMesTypeMapping_.insert({XpowerMessageType::APP_DETAIL, OptimizeMessageType::MESSAGE_APP_DETAIL});
procMesTypeMapping_.insert({XpowerMessageType::COMPONENT_TOP, OptimizeMessageType::MESSAGE_COMPONENT_TOP});
procMesTypeMapping_.insert({XpowerMessageType::ABNORMAL_EVENTS, OptimizeMessageType::MESSAGE_ABNORMAL_EVENTS});
}
XpowerPlugin::~XpowerPlugin() {}
@ -45,9 +45,9 @@ int XpowerPlugin::Start(const uint8_t *configData, uint32_t configSize)
HILOG_INFO(LOG_CORE, "%s:config data -->configSize=%d", __func__, configSize);
CHECK_TRUE(configData != nullptr, -1, "XpowerPlugin error: param invalid!!!");
// 反序列化
CHECK_TRUE(protoConfig.ParseFromArray(configData, configSize) > 0, -1, "%s:parseFromArray failed!", __func__);
CHECK_TRUE(protoConfig_.ParseFromArray(configData, configSize) > 0, -1, "%s:parseFromArray failed!", __func__);
uint32_t messageType = static_cast<uint32_t>(OptimizeMessageType::MESSAGE_OPTIMIZE_STOP);
std::string bundleName = protoConfig.bundle_name();
std::string bundleName = protoConfig_.bundle_name();
if (bundleName.empty()) {
HILOG_ERROR(LOG_CORE, "XpowerPlugin error : bundle name is empty!");
return -1;
@ -65,9 +65,9 @@ int XpowerPlugin::Start(const uint8_t *configData, uint32_t configSize)
HILOG_ERROR(LOG_CORE, "the bundle name %s is not supported", bundleName.c_str());
return -1;
}
if (protoConfig.message_type().size() > 0) {
for (int i = 0; i < protoConfig.message_type().size(); i++) {
uint32_t mesType = procMesTypeMapping[static_cast<XpowerMessageType>(protoConfig.message_type(i))];
if (protoConfig_.message_type().size() > 0) {
for (int i = 0; i < protoConfig_.message_type().size(); i++) {
uint32_t mesType = procMesTypeMapping_[static_cast<XpowerMessageType>(protoConfig_.message_type(i))];
messageType |= mesType;
}
}
@ -83,29 +83,29 @@ int XpowerPlugin::Start(const uint8_t *configData, uint32_t configSize)
bool XpowerPlugin::StartPowerManager(std::uint32_t messageType, std::string &bundleName)
{
if (powerClientHandle == nullptr) {
powerClientHandle = dlopen("/system/lib64/libxpower_manager_client.z.so", RTLD_LAZY);
if (powerClientHandle_ == nullptr) {
powerClientHandle_ = dlopen("/system/lib64/libxpower_manager_client.z.so", RTLD_LAZY);
}
if (powerClientHandle == nullptr) {
if (powerClientHandle_ == nullptr) {
HILOG_ERROR(LOG_CORE, "%s :fail to open libxpower_manager_client.z.so", __func__);
return false;
}
// 注册回调
StartOptimizeMode startOptimizeMode = (StartOptimizeMode)dlsym(powerClientHandle, "StartOptimizeC");
StartOptimizeMode startOptimizeMode = (StartOptimizeMode)dlsym(powerClientHandle_, "StartOptimizeC");
if (startOptimizeMode == nullptr) {
HILOG_ERROR(LOG_CORE, "Failed to dlsy startOptimizeMode");
return false;
}
config.messageType = messageType;
config.packageName = bundleName;
config.callback = std::bind(&XpowerPlugin::OptimizeCallback, this, std::placeholders::_1, std::placeholders::_2,
config_.messageType = messageType;
config_.packageName = bundleName;
config_.callback = std::bind(&XpowerPlugin::OptimizeCallback, this, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3);
listenerHandle = startOptimizeMode(config);
if (listenerHandle == nullptr) {
listenerHandle_ = startOptimizeMode(config_);
if (listenerHandle_ == nullptr) {
HILOG_ERROR(LOG_CORE, "Failed to startOptimizeMode");
return false;
}
dataQueuePtr = std::make_shared<PowerMessageQueue>(MAX_QUEUE_SIZE);
dataQueuePtr_ = std::make_shared<PowerMessageQueue>(MAX_QUEUE_SIZE);
return true;
}
@ -124,21 +124,21 @@ void XpowerPlugin::OptimizeCallback(const std::uint32_t messageType, const uint8
}
rawData->length = protoSize;
rawData->messageType = messageType;
dataQueuePtr->PushBack(rawData);
if (resultWriter != nullptr) {
resultWriter->write(resultWriter, protoData, protoSize);
resultWriter->flush(resultWriter);
dataQueuePtr_->PushBack(rawData);
if (resultWriter_ != nullptr) {
resultWriter_->write(resultWriter_, protoData, protoSize);
resultWriter_->flush(resultWriter_);
}
}
int XpowerPlugin::Report(uint8_t *data, uint32_t dataSize)
{
HILOG_INFO(LOG_CORE, "power: report the data to caller");
if (dataQueuePtr->Empty()) {
if (dataQueuePtr_->Empty()) {
return 0;
}
std::shared_ptr<PowerOptimizeData> result = nullptr;
if (!dataQueuePtr->WaitAndPop(result, std::chrono::milliseconds(g_waitDuration))) {
if (!dataQueuePtr_->WaitAndPop(result, std::chrono::milliseconds(WAIT_DURATION))) {
HILOG_ERROR(LOG_CORE, "fetch data error!");
return 0;
}
@ -155,24 +155,24 @@ int XpowerPlugin::Report(uint8_t *data, uint32_t dataSize)
void XpowerPlugin::SetWriter(WriterStruct *writer)
{
resultWriter = writer;
resultWriter_ = writer;
}
int XpowerPlugin::Stop()
{
HILOG_INFO(LOG_CORE, "%s:begin to stop xpower plugin", __func__);
StopOptimizeMode stopOptimizeMode = (StopOptimizeMode)dlsym(powerClientHandle, "StopOptimizeC");
StopOptimizeMode stopOptimizeMode = (StopOptimizeMode)dlsym(powerClientHandle_, "StopOptimizeC");
if (stopOptimizeMode == nullptr) {
HILOG_ERROR(LOG_CORE, "Faile to dlsym StopOptimizeC");
return -1;
}
if (listenerHandle != nullptr) {
stopOptimizeMode(listenerHandle);
if (listenerHandle_ != nullptr) {
stopOptimizeMode(listenerHandle_);
HILOG_INFO(LOG_CORE, "stop xpower plugin callback");
}
if (powerClientHandle != nullptr) {
dlclose(powerClientHandle);
if (powerClientHandle_ != nullptr) {
dlclose(powerClientHandle_);
}
dataQueuePtr->ShutDown();
dataQueuePtr_->ShutDown();
return 0;
}

View File

@ -1,4 +1,4 @@
# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
# Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
# 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* 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
@ -120,6 +120,7 @@ HWTEST_F(XpowerPluginTest, TestStartFail, TestSize.Level1)
WriterStruct writer = {WriteFunc, FlushFunc};
// set config
config.set_bundle_name("");
config.add_message_type(XpowerMessageType::REAL_BATTERY);
// test plugin process
plugin.SetWriter(&writer);
// serialize
@ -131,7 +132,6 @@ HWTEST_F(XpowerPluginTest, TestStartFail, TestSize.Level1)
EXPECT_NE(plugin.Start(configData.data(), configData.size()), 0);
EXPECT_NE(plugin.Start(nullptr, configData.size()), 0);
EXPECT_NE(plugin.Start(configData.data(), 0), 0);
plugin.Stop();
#endif
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* 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

View File

@ -170,9 +170,6 @@ bool ProfilerService::SessionContext::StopPluginSessions()
if (offlineTask.size() > 0) {
ScheduleTaskManager::GetInstance().UnscheduleTask(offlineTask);
offlineTask = "";
} else {
// timeout or active called StopPluginSessions.
return true;
}
}

View File

@ -232,6 +232,7 @@ bool TraceFileWriter::Finish()
stream_.write(reinterpret_cast<CharPtr>(&header_), sizeof(header_));
CHECK_TRUE(stream_, false, "write final header to %s failed!", path_.c_str());
CHECK_TRUE(stream_.flush(), false, "binary file %s flush failed!", path_.c_str());
HILOG_INFO(LOG_CORE, "Finish: %s, bytes: %" PRIu64 ", count: %" PRIu64, path_.c_str(), writeBytes_, writeCount_);
return true;
}

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/services"
##############################fuzztest##########################################
ohos_fuzztest("ProfilerCreateSessionFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/services/profiler_service/test/fuzztest/profilercreatesession_fuzzer"
include_dirs = [
"../../../include",

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/services"
##############################fuzztest##########################################
ohos_fuzztest("ProfilerDestroySessionFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/services/profiler_service/test/fuzztest/profilerdestroysession_fuzzer"
include_dirs = [
"../../../include",

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/services"
##############################fuzztest##########################################
ohos_fuzztest("ProfilerFetchDataFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/services/profiler_service/test/fuzztest/profilerfetchdata_fuzzer"
include_dirs = [
"../../../include",

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/services"
##############################fuzztest##########################################
ohos_fuzztest("ProfilerGetCapabilitiesFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/services/profiler_service/test/fuzztest/profilergetcapabilities_fuzzer"
include_dirs = [
"../../../include",

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/services"
##############################fuzztest##########################################
ohos_fuzztest("ProfilerKeepSessionFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/services/profiler_service/test/fuzztest/profilerkeepsession_fuzzer"
include_dirs = [
"../../../include",

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/services"
##############################fuzztest##########################################
ohos_fuzztest("ProfilerStartSessionFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/services/profiler_service/test/fuzztest/profilerstartsession_fuzzer"
include_dirs = [
"../../../include",

View File

@ -14,11 +14,10 @@
#####################hydra-fuzz###################
import("//build/test.gni")
import("../../../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/services"
##############################fuzztest##########################################
ohos_fuzztest("ProfilerStopSessionFuzzTest") {
module_out_path = module_output_path
module_out_path = hiprofiler_fuzz_output_path
fuzz_config_file = "${OHOS_PROFILER_DIR}/device/services/profiler_service/test/fuzztest/profilerstopsession_fuzzer"
include_dirs = [
"../../../include",

View File

@ -19,45 +19,37 @@
#include "include/ByTrace.h"
namespace OHOS {
namespace SmartPerf {
void ByTrace::SetTraceConfig(int mSum, int mInterval, long long mThreshold) const
void ByTrace::SetTraceConfig(int mSum, int mInterval, long long mThreshold, int mLowfps) const
{
sum = mSum;
interval = mInterval;
threshold = mThreshold;
lowfps = mLowfps;
}
void ByTrace::SetTraceCmd(std::string mTraceCmd) const
{
traceCmd = mTraceCmd;
}
void ByTrace::ThreadGetTrace() const
{
std::string result;
SPUtils::LoadCmd(std::string("bytrace --trace_begin --overwrite"), result);
std::cout << "TRACE threadGetTrace >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
}
void ByTrace::ThreadEndTrace() const
{
std::string result;
SPUtils::LoadCmd(std::string("bytrace --trace_finish --overwrite"), result);
std::cout << "TRACE threadGetTrace >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
}
void ByTrace::ThreadFinishTrace(const std::string &pathName) const
{
std::string result;
std::stringstream sstream;
std::string time = std::to_string(SPUtils::GetCurTime());
sstream.str("");
sstream << "bytrace --overwrite sched ace app disk ohos graphic sync workq ability";
sstream << " > /data/app/el2/100/base/com.ohos.gameperceptio/haps/entry/files/sptrace_";
sstream << pathName << ".ftrace";
const std::string &cmdTraceOverwrite = sstream.str();
SPUtils::LoadCmd(cmdTraceOverwrite, result);
std::cout << "TRACE threadFinishTrace >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
sstream << traceCmd;
sstream << " > /data/app/el2/100/base/com.ohos.smartperf/haps/entry/files/sptrace_";
sstream << time << ".ftrace";
std::string traceCmdExe = sstream.str();
SPUtils::LoadCmd(traceCmdExe, result);
std::cout << "TRACE threadGetTrace >> CMD >>" << traceCmdExe << std::endl;
}
TraceStatus ByTrace::CheckFpsJitters(std::vector<long long> jitters)
TraceStatus ByTrace::CheckFpsJitters(std::vector<long long> jitters, int cfps)
{
long long curTime = SPUtils::GetCurTime();
if (curNum <= sum && curTriggerFlag < 0) {
for (size_t i = 0; i < jitters.size(); i++) {
long long normalJitter = jitters[i] / 1e6;
if (normalJitter > threshold) {
if (normalJitter > threshold || cfps < lowfps) {
TriggerCatch(curTime);
}
}
@ -65,20 +57,14 @@ TraceStatus ByTrace::CheckFpsJitters(std::vector<long long> jitters)
std::cout << "TRACE CHECK RUNING >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
std::cout << "TRACE CHECK lastTriggerTime:" << lastTriggerTime << " curTime:" << curTime << " curTriggerFlag:" <<
curTriggerFlag << std::endl;
if ((curTime - lastTriggerTime) > cost && curTriggerFlag > 0) {
std::string result;
SPUtils::LoadCmd(std::string("bytrace --trace_finish"), result);
std::string pathName = std::to_string(curTime);
std::thread tFinish(&ByTrace::ThreadFinishTrace, this, std::ref(pathName));
if ((curTime - lastTriggerTime) / 1e3 > interval && curTriggerFlag == 1) {
curTriggerFlag = -1;
std::cout << "TRACE FINISH >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
tFinish.detach();
}
return TraceStatus::TRACE_FINISH;
}
void ByTrace::TriggerCatch(long long curTime) const
{
if ((curTime - lastTriggerTime) > interval) {
if ((curTime - lastTriggerTime) / 1e3 > interval) {
std::thread tStart(&ByTrace::ThreadGetTrace, this);
curTriggerFlag = 1;
lastTriggerTime = curTime;

View File

@ -38,7 +38,7 @@ std::map<std::string, std::string> FPS::ItemData()
}
result["fpsJitters"] = jitterStr;
if (isCatchTrace > 0) {
ByTrace::GetInstance().CheckFpsJitters(fpsInfo.jitters);
ByTrace::GetInstance().CheckFpsJitters(fpsInfo.jitters, fpsInfo.fps);
}
if (isCapture > 0) {
Capture::GetInstance().TriggerGetCatch(SPUtils::GetCurTime());

View File

@ -64,7 +64,7 @@ std::string ControlCallCmd::GetResult(int argc, std::vector<std::string> v)
result = "time:" + stream.str();
} else if (v[typeName] == "fps") {
result = SmartPerf::ControlCallCmd::SlideFps(v);
} else if (v[typeName] == "pagefps") {
} else if (v[typeName] == "pagefps") {
double fps = SmartPerf::ControlCallCmd::PageFps();
stream << fps;
result = "FPS:" + stream.str() + "fps";
@ -78,7 +78,7 @@ std::string ControlCallCmd::GetResult(int argc, std::vector<std::string> v)
SPUtils::LoadCmd("GP_daemon_fps 10", result);
}
if (time == noNameType) {
std::cout << "Startup error, unknown application or application not responding"<< std::endl;
std::cout << "Startup error, unknown application or application not responding" << std::endl;
} else {
std::cout << result << std::endl;
}
@ -146,7 +146,7 @@ double ControlCallCmd::ResponseTime()
SPUtils::LoadCmd("rm -rfv /data/local/tmp/*.ftrace", cmdResult);
std::string traceName = std::string("/data/local/tmp/") + std::string("sp_trace_") + "response" + ".ftrace";
std::thread thGetTrace = sd.ThreadGetTrace("response", traceName);
if (isOhTest) {
if (isOhTest) {
thGetTrace.join();
time = pcrt.ParseResponseTrace(traceName);
} else {

View File

@ -25,15 +25,13 @@ public:
return instance;
}
// trace配置
void SetTraceConfig(int mSum, int mInterval, long long mThreshold) const;
void SetTraceConfig(int mSum, int mInterval, long long mThreshold, int mLowfps) const;
// 开始抓trace线程
void ThreadGetTrace() const;
// 结束trace线程
void ThreadEndTrace() const;
// 结束抓trace线程
void ThreadFinishTrace(const std::string &pathName) const;
// trace命令配置
void SetTraceCmd(std::string traceCmd) const;
// 校验fps-jitters
TraceStatus CheckFpsJitters(std::vector<long long> jitters);
TraceStatus CheckFpsJitters(std::vector<long long> jitters, int cfps);
// 触发trace
void TriggerCatch(long long curTime) const;
@ -48,14 +46,16 @@ private:
mutable int curNum = 0;
// 抓trace间隔(两次抓取的间隔时间 默认60*1000 ms)
mutable int interval = 60000;
// 抓trace耗时(start 到 finish的预留时间 默认10*1000 ms)
mutable int cost = 10000;
// 抓trace触发条件:默认 某一帧的某个jitter>100 ms触发
mutable long long threshold = 100;
// 上一次触发时间
mutable long long lastTriggerTime = -1;
// 当前是否触发
mutable long long curTriggerFlag = -1;
//traceCmd
mutable std::string traceCmd = "";
//低帧触发
mutable int lowfps = -1;
};
}
}

View File

@ -32,8 +32,8 @@ enum class MessageType {
GET_TEMPERATURE,
GET_POWER,
GET_CAPTURE,
CATCH_TRACE_START,
CATCH_TRACE_FINISH,
CATCH_TRACE_CONFIG,
CATCH_TRACE_CMD,
SET_DUBAI_DB
};
@ -51,8 +51,8 @@ const std::unordered_map<MessageType, std::string> messageMap = {
{ MessageType::GET_TEMPERATURE, std::string("get_temperature") },
{ MessageType::GET_POWER, std::string("get_power") },
{ MessageType::GET_CAPTURE, std::string("get_capture") },
{ MessageType::CATCH_TRACE_START, std::string("catch_trace_start") },
{ MessageType::CATCH_TRACE_FINISH, std::string("catch_trace_end") },
{ MessageType::CATCH_TRACE_CONFIG, std::string("catch_trace_config") },
{ MessageType::CATCH_TRACE_CMD, std::string("catch_trace_cmd") },
{ MessageType::SET_DUBAI_DB, std::string("set_dubai_db") },
};

View File

@ -23,6 +23,8 @@ public:
static SpProfiler *GetProfilerItem(MessageType messageType);
static void SetProfilerPkg(std::string pkg);
static void SetProfilerPid(std::string pid);
static void SetByTrace(std::string message);
static void SetByTraceCmd(std::string cmd);
static SpProfiler *GetCmdProfilerItem(CommandType commandType);
};
}

View File

@ -53,17 +53,7 @@ public:
spSocket.Init(type);
if (type == ProtoType::TCP) {
std::cout << "Socket TCP Init called!" << std::endl;
while (1) {
int procFd = spSocket.Accept();
std::cout << "Socket TCP procFd: " << procFd << std::endl;
while (procFd > 0) {
spSocket.Recv();
std::string recvStr = spSocket.RecvBuf();
std::cout << "Socket TCP Recv: " << recvStr << std::endl;
// 解析消息 分发处理
DealMsg(recvStr, spSocket);
}
}
TypeTcp(spSocket);
}
if (type == ProtoType::UDP) {
while (1) {
@ -74,6 +64,21 @@ public:
std::cout << "Socket Process finished!" << std::endl;
spSocket.Close();
}
void TypeTcp(SpServerSocket spSocket) const
{
while (1) {
int procFd = spSocket.Accept();
std::cout << "Socket TCP procFd: " << procFd << std::endl;
while (procFd > 0) {
int reFd = spSocket.Recv();
if (reFd < 0) break;
std::string recvStr = spSocket.RecvBuf();
std::cout << "Socket TCP Recv: " << recvStr << std::endl;
// 解析消息 分发处理
DealMsg(recvStr, spSocket);
}
}
}
// TCP
void DealMsg(std::string recvStr, SpServerSocket &spSocket) const
{
@ -107,6 +112,11 @@ public:
}
}
vec.push_back(recvStr.substr(j, size - j));
const int type = 2;
if (vec[type] == "findAppPage") {
std::string cmdResult;
SPUtils::LoadCmd("uinput -T -m 600 2760 600 1300 200", cmdResult);
}
OHOS::SmartPerf::ControlCallCmd controlCallCmd;
std::string result = controlCallCmd.GetResult(vec.size(), vec);
spSocket.Send(result);
@ -131,6 +141,10 @@ public:
spSocket.Sendto(curPkgName);
} else if (profiler == nullptr && (iterator->first == MessageType::SET_PROCESS_ID)) {
SpProfilerFactory::SetProfilerPid(SplitMsg(recvBuf));
} else if (profiler == nullptr && (iterator->first == MessageType::CATCH_TRACE_CONFIG)) {
SpProfilerFactory::SetByTrace(SplitMsg(recvBuf));
} else if (profiler == nullptr && (iterator->first == MessageType::CATCH_TRACE_CMD)) {
SpProfilerFactory::SetByTraceCmd(SplitMsg(recvBuf));
} else if (profiler == nullptr) {
std::string returnStr = iterator->second;
spSocket.Sendto(returnStr);

View File

@ -54,15 +54,9 @@ SpProfiler *SpProfilerFactory::GetProfilerItem(MessageType messageType)
case MessageType::GET_POWER:
profiler = &Power::GetInstance();
break;
case MessageType::CATCH_TRACE_START:
ByTrace::GetInstance().ThreadGetTrace();
break;
case MessageType::CATCH_TRACE_FINISH: {
ByTrace::GetInstance().ThreadEndTrace();
std::string curTime = std::to_string(SPUtils::GetCurTime());
ByTrace::GetInstance().ThreadFinishTrace(curTime);
case MessageType::CATCH_TRACE_CONFIG:
FPS::GetInstance().SetTraceCatch();
break;
}
case MessageType::GET_CAPTURE:
FPS::GetInstance().SetCaptureOn();
break;
@ -82,6 +76,40 @@ void SpProfilerFactory::SetProfilerPkg(std::string pkg)
FPS &fps = FPS::GetInstance();
fps.SetPackageName(pkg);
}
void SpProfilerFactory::SetByTraceCmd(std::string cmd)
{
ByTrace &bTrace = ByTrace::GetInstance();
bTrace.SetTraceCmd(cmd);
}
void SpProfilerFactory::SetByTrace(std::string message)
{
std::vector<std::string> values;
std::string delimiter = "||";
std::string delim = "=";
SPUtils::StrSplit(message, delimiter, values);
int mSum = 0;
int mInterval = 0;
long long mThreshold = 0;
int lowFps = 0;
for (std::string vItem:values) {
std::vector<std::string> vItems;
SPUtils::StrSplit(vItem, delim, vItems);
if (vItems[0] == "traceSum") {
mSum = std::stoi(vItems[1]);
}
if (vItems[0] == "fpsJitterTime") {
mThreshold = std::stoi(vItems[1]);
}
if (vItems[0] == "catchInterval") {
mInterval = std::stoi(vItems[1]);
}
if (vItems[0] == "lowFps") {
lowFps = std::stoi(vItems[1]);
}
}
ByTrace &bTrace = ByTrace::GetInstance();
bTrace.SetTraceConfig(mSum, mInterval, mThreshold, lowFps);
}
void SpProfilerFactory::SetProfilerPid(std::string pid)
{
RAM &ram = RAM::GetInstance();

View File

@ -65,7 +65,10 @@ action("stream_data_cpp_gen") {
rebase_path(".", root_build_dir),
]
args += rebase_path(sources, root_build_dir)
deps = [ "${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protoc(${host_toolchain})" ]
deps = [
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protoc(${host_toolchain})",
"${OHOS_PROFILER_DIR}/device/services/ipc:protoencoder_plugin(${host_toolchain})",
]
}
ohos_source_set("stream_data_cpp") {