diff --git a/BUILD.gn b/BUILD.gn index 677648e86fdddb8dfbda3f9dc42a699559d2f8a1..32931f424bf7f89c8d6982d7e31e460bba61cb6a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -135,9 +135,7 @@ sources_platform_with_ts_common = [ ] if (hiperf_debug) { - sources_platform_with_ts_common += [ - "./src/debug_logger.cpp", - ] + sources_platform_with_ts_common += [ "./src/debug_logger.cpp" ] } sources_platform_common = [ @@ -157,9 +155,7 @@ if (is_ohos) { } if (hiperf_debug) { - sources_platform_common += [ - "./src/option_debug.cpp", - ] + sources_platform_common += [ "./src/option_debug.cpp" ] } sources_platform_linux = [ @@ -226,6 +222,9 @@ ohos_source_set("hiperf_platform_common") { "samgr:samgr_proxy", ] defines += [ "CONFIG_HAS_CCM" ] + if (hiperf_feature_pc) { + defines += [ "is_pc=${hiperf_feature_pc}" ] + } if (bundle_framework_enable) { external_deps += [ "bundle_framework:appexecfwk_base", @@ -273,6 +272,9 @@ ohos_source_set("hiperf_platform_linux") { "init:libbegetutil", ] defines = [ "CONFIG_HAS_CCM" ] + if (hiperf_feature_pc) { + defines += [ "is_pc=${hiperf_feature_pc}" ] + } } else { external_deps = [ "faultloggerd:unwinder_host" ] } @@ -463,7 +465,7 @@ ohos_executable("hiperf") { ohos_executable("hiperf_host") { sources = [ "./src/main.cpp" ] - + deps = [ ":hiperf_platform_common" ] external_deps = [ diff --git a/bundle.json b/bundle.json index 644393742a9a10fdf818ca1c64a1cbece813c49e..0eb7d84b4b45daab29372da9f17494c6a1137676 100644 --- a/bundle.json +++ b/bundle.json @@ -12,6 +12,9 @@ "component": { "name": "hiperf", "subsystem": "developtools", + "features": [ + "hiperf_feature_pc" + ], "adapted_system_type": [ "standard" ], diff --git a/etc/hiperf.cfg b/etc/hiperf.cfg index a87ab47cde9ef1c7281104c2ccd7897be33ce6a8..cdd12e5856156993b34ed2ce77307d0bfd96a916 100644 --- a/etc/hiperf.cfg +++ b/etc/hiperf.cfg @@ -2,7 +2,7 @@ "jobs": [{ "name": "post-fs-data", "cmds": [ - "mkdir /data/log/hiperflog 0770 shell shell", + "mkdir /data/log/hiperflog 0777 shell shell", "restorecon /data/log/hiperflog", "chmod 0666 /dev/lperf" ] diff --git a/hiperf.gni b/hiperf.gni index 8123bff6fae3c5a8d40c5726c3dc5f7d47d3f812..c0664846fa1d2bba8b85db089ac19e6ee0031039 100644 --- a/hiperf.gni +++ b/hiperf.gni @@ -34,6 +34,7 @@ declare_args() { hiperf_independent_compilation = true bundle_framework_enable = false ability_base_enable = false + hiperf_feature_pc = false if (defined(global_parts_info) && defined(global_parts_info.bundlemanager_bundle_framework)) { bundle_framework_enable = true diff --git a/include/subcommand_record.h b/include/subcommand_record.h index 14eea9be9e3c0711354d36b4b2350ab405b1455d..3a9e9d7a8c85ad02d55b690fcc7edbc1ad31bef2 100644 --- a/include/subcommand_record.h +++ b/include/subcommand_record.h @@ -68,7 +68,11 @@ public: "Usage: hiperf record [options] [command [command-args]]\n" " Collect performance sampling information of running [command].\n" " The default options are: -c --cpu-limit 25 -d 10000.0 -e hw-cpu-cycles\n" +#if defined(is_pc) && is_pc + " -f 4000 -m 1024 -o /data/storage/el2/base/cache/perf.data.\n" +#else " -f 4000 -m 1024 -o /data/local/tmp/perf.data.\n" +#endif " -a\n" " Collect system-wide information.\n" " for measures all processes/threads\n" @@ -169,7 +173,11 @@ public: " --data-limit \n" " Stop recording after SIZE bytes of records. Default is unlimited.\n" " -o \n" +#if defined(is_pc) && is_pc + " Set output file name, default is specified by the TMPDIR environment variable.\n" +#else " Set output file name, default is /data/local/tmp/perf.data.\n" +#endif " -z\n" " Compress record data.\n" " --restart\n" @@ -248,7 +256,11 @@ private: int cmdlinesSize_ = DEFAULT_SAVED_CMDLINES_SIZE; int oldCmdlinesSize_ = 0; std::vector symbolDir_ = {}; +#if defined(is_pc) && is_pc + std::string outputFilename_ = "/data/storage/el2/base/cache/perf.data"; +#else std::string outputFilename_ = "/data/local/tmp/perf.data"; +#endif std::string appPackage_ = {}; int checkAppMs_ = DEFAULT_CHECK_APP_MS; std::string clockId_ = {}; diff --git a/include/subcommand_stat.h b/include/subcommand_stat.h index 6adfc88ef97bba1e10a453ceb07b0d6b1641b14b..e337a1d32d1ecb601fd875a1892c7f16ec1f3716 100644 --- a/include/subcommand_stat.h +++ b/include/subcommand_stat.h @@ -90,7 +90,11 @@ public: " start: start counting\n" " stop: stop counting\n" " -o \n" +#if defined(is_pc) && is_pc + " Set output file name, default is specified by the TMPDIR environment variable.\n" +#else " Set output file name, default is /data/local/tmp/perf_stat.txt.\n" +#endif " Only restrain using with --control prepare.\n" // clang-format on ), diff --git a/include/utilities.h b/include/utilities.h index 8dca5e7e88ea28fccaa90d8bed9799c60918e2d9..9d56a309aec8de9222712e3c1fdf2e52fbd97b45 100644 --- a/include/utilities.h +++ b/include/utilities.h @@ -418,6 +418,8 @@ cJSON* ParseJson(const std::string &filePath); bool GetJsonNum(cJSON* tag, const char* key, size_t &value); bool GetCfgValue(const char* cfgPath, const char* cfgKey, size_t &value); #endif + +void GetDefaultPathByEnv(std::string& outputFilename, const std::string fileType); } // namespace HiPerf } // namespace Developtools } // namespace OHOS diff --git a/src/subcommand_record.cpp b/src/subcommand_record.cpp index b1f53e4f568cd53614e5809d80e06945e5cc1cc4..f9047f17ced48e1c8d75a28c66907e1d6ff9621c 100644 --- a/src/subcommand_record.cpp +++ b/src/subcommand_record.cpp @@ -589,6 +589,8 @@ bool SubCommandRecord::ParseOption(std::vector &args) #ifdef CONFIG_HAS_CCM GetMmapPagesCfg(); #endif + const std::string fileType = "perf.data"; + GetDefaultPathByEnv(outputFilename_, fileType); if (!GetOptions(args)) { return false; } @@ -1676,9 +1678,14 @@ HiperfError SubCommandRecord::OnSubCommand(std::vector& args) ChildResponseToMain(false); CloseClientThread(); } +#if defined(is_pc) && is_pc + HLOGE("Fail to create record file"); + HIPERF_HILOGE(MODULE_DEFAULT, "[OnSubCommand] Fail to create record file"); +#else HLOGE("Fail to create record file %s", outputFilename_.c_str()); HIPERF_HILOGE(MODULE_DEFAULT, "[OnSubCommand] Fail to create record file %{public}s", outputFilename_.c_str()); +#endif return HiperfError::CREATE_OUTPUT_FILE_FAIL; } HIPERF_HILOGI(MODULE_DEFAULT, "[OnSubCommand] CreateInitRecordFile finished"); @@ -1725,8 +1732,13 @@ HiperfError SubCommandRecord::OnSubCommand(std::vector& args) startSaveFileTimes_ = steady_clock::now(); if (!backtrack_) { if (!FinishWriteRecordFile()) { +#if defined(is_pc) && is_pc + HLOGE("Fail to finish record file"); + HIPERF_HILOGE(MODULE_DEFAULT, "Fail to finish record file"); +#else HLOGE("Fail to finish record file %s", outputFilename_.c_str()); HIPERF_HILOGE(MODULE_DEFAULT, "Fail to finish record file %{public}s", outputFilename_.c_str()); +#endif return HiperfError::FINISH_WRITE_RECORD_FILE_FAIL; } else if (!PostProcessRecordFile()) { HLOGE("Fail to post process record file"); @@ -2079,8 +2091,11 @@ bool SubCommandRecord::CreateInitRecordFile(bool compressData) CHECK_TRUE(fileWriter_->WriteAttrAndId(perfEvents_.GetAttrWithId(), isSpe_), false, 0, ""); CHECK_TRUE(AddFeatureRecordFile(), false, 0, ""); - +#if defined(is_pc) && is_pc + HLOGD("create new record file"); +#else HLOGD("create new record file %s", outputFilename_.c_str()); +#endif return true; } @@ -2102,14 +2117,22 @@ bool SubCommandRecord::PostProcessRecordFile() fileWriter_.reset(); if (!CreateInitRecordFile(compressData_)) { // create again +#if defined(is_pc) && is_pc + HLOGEP("Fail to open data file"); +#else HLOGEP("Fail to open data file %s ", outputFilename_.c_str()); +#endif return false; } // read temp file auto fileReader = PerfFileReader::Instance(tempFileName); if (fileReader == nullptr) { +#if defined(is_pc) && is_pc + HLOGEP("Fail to open data file"); +#else HLOGEP("Fail to open data file %s ", tempFileName.c_str()); +#endif return false; } @@ -2412,7 +2435,9 @@ bool SubCommandRecord::OnlineReportData() } std::unique_ptr reporter = std::make_unique(); +#ifndef is_pc HLOGD("report the file %s to report file %s \n", tempFileName.c_str(), outputFilename_.c_str()); +#endif std::vector args; args.emplace_back("-i"); args.emplace_back(tempFileName); diff --git a/src/subcommand_stat.cpp b/src/subcommand_stat.cpp index 41db0ee48c2b8e0addf369c97da8e1cf1b6aae8d..87106ced62ae4e94635e5cfd96bf066d706e6d0e 100644 --- a/src/subcommand_stat.cpp +++ b/src/subcommand_stat.cpp @@ -37,7 +37,11 @@ const uint16_t THOUSANDS_SEPARATOR = 3; namespace OHOS { namespace Developtools { namespace HiPerf { +#if defined(is_pc) && is_pc +const std::string DEFAULT_STAT_FILE = "/data/storage/el2/base/cache/perf_stat.txt"; +#else const std::string DEFAULT_STAT_FILE = "/data/local/tmp/perf_stat.txt"; +#endif // when there are many events, start record will take more time. const std::chrono::milliseconds CONTROL_WAITREPY_TIMEOUT = 2000ms; static std::map thread_map_; @@ -911,7 +915,7 @@ HiperfError SubCommandStat::CheckStatOption() if (!CheckRestartOption(appPackage_, targetSystemWide_, restart_, selectPids_)) { return HiperfError::CHECK_RESTART_OPTION_FAIL; } - + // check option if (!CheckSelectCpuPidOption()) { return HiperfError::CHECK_SELECT_CPU_PID_FAIL; @@ -1155,6 +1159,8 @@ bool SubCommandStat::CheckOutPutFile() } if (outputFilename_.empty()) { outputFilename_ = DEFAULT_STAT_FILE; + const std::string fileType = "perf_stat.txt"; + GetDefaultPathByEnv(outputFilename_, fileType); } if (!IsValidOutPath(outputFilename_)) { printf("Invalid output file path, permission denied\n"); diff --git a/src/utilities.cpp b/src/utilities.cpp index 696b78356ec790cbcc0d07f81a70f98e8bb32dd1..b1e4df060be7450b2e0761dbb675a6db252b3d70 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -1074,6 +1074,21 @@ void AgeHiperflogFiles() } #endif } + +void GetDefaultPathByEnv(std::string& outputFilename, const std::string fileType) +{ +#if defined(is_pc) && is_pc + char* outputPathEnv = std::getenv("TMPDIR"); + if (outputPathEnv != nullptr && strlen(outputPathEnv) > 0) { + outputFilename = outputPathEnv; + std::string fileName = StringEndsWith(outputFilename, "/") ? fileType : "/" + fileType; + outputFilename += fileName; + HIPERF_HILOGI(MODULE_DEFAULT, "get TMPDIR env success"); + } else { + HIPERF_HILOGE(MODULE_DEFAULT, "get TMPDIR env failed"); + } +#endif +} } // namespace HiPerf } // namespace Developtools } // namespace OHOS diff --git a/test/BUILD.gn b/test/BUILD.gn index aabe9d065cf4bff5c576209eca73f44f7eaa59fc..38e0aa972ec1404ecce1329f7404b4440cf9a9a7 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -113,6 +113,10 @@ ohos_unittest("hiperf_unittest") { "CONFIG_HAS_CCM", ] + if (hiperf_feature_pc) { + defines += [ "is_pc=${hiperf_feature_pc}" ] + } + public_deps = [] external_deps = [ "abseil-cpp:absl_container", diff --git a/test/unittest/common/native/subcommand_record_test.cpp b/test/unittest/common/native/subcommand_record_test.cpp index 32f6c87ee62b7274a44c6c1b0d410c82c0cb47fd..648243f3699da5a4cc9a42e345c38d7b6c7c3904 100644 --- a/test/unittest/common/native/subcommand_record_test.cpp +++ b/test/unittest/common/native/subcommand_record_test.cpp @@ -2544,6 +2544,25 @@ HWTEST_F(SubCommandRecordTest, UpdateDevHostMaps4, TestSize.Level1) cmd.UpdateDevHostMaps(recordIn); EXPECT_EQ(recordIn.data_.addr, addr); } + +HWTEST_F(SubCommandRecordTest, CheckPcRecordPath, TestSize.Level1) +{ + SubCommandRecord cmd; + string defaultName = "/data/storage/el2/base/cache/perf.data"; +#if defined(is_pc) && is_pc + EXPECT_EQ(cmd.outputFilename_, defaultName); + cmd.ParseOption({}); + char* outputPathEnv = std::getenv("TMPDIR"); + if (outputPathEnv != nullptr && strlen(outputPathEnv) > 0) { + string outputFilename = outputPathEnv; + std::string fileName = StringEndsWith(outputFilename, "/") ? "perf.data" : "/perf.data"; + outputFilename += fileName; + EXPECT_EQ(cmd.outputFilename_, outputFilename); + } else { + EXPECT_EQ(cmd.outputFilename_, defaultName); + } +#endif +} } // namespace HiPerf } // namespace Developtools } // namespace OHOS diff --git a/test/unittest/common/native/subcommand_stat_test.cpp b/test/unittest/common/native/subcommand_stat_test.cpp index c87c083ab98f0b26051dd81f8df350786fd24069..1648820178219a4dba986e92913fa47ba9a595b4 100644 --- a/test/unittest/common/native/subcommand_stat_test.cpp +++ b/test/unittest/common/native/subcommand_stat_test.cpp @@ -2451,7 +2451,7 @@ HWTEST_F(SubCommandStatTest, TestOnSubCommand_control05, TestSize.Level1) const std::string expectedStr = "was not stopped within 30 seconds"; std::string tempOutputFile = "/data/local/tmp/stat_test_output.tmp"; std::string cmdWithOutput = testCmd + " > " + tempOutputFile + " 2>&1"; - + int ret = system((cmdWithOutput + " &").c_str()); ASSERT_EQ(ret, 0); @@ -2518,6 +2518,26 @@ HWTEST_F(SubCommandStatTest, OutPutFileName02, TestSize.Level1) EXPECT_EQ(CheckTraceCommandOutput("hiperf stat --control prepare -a -o /data/log/hiperflog/stat.txt", {"Invalid output file path, permission denied"}), true); } + +HWTEST_F(SubCommandStatTest, CheckPcStatPath, TestSize.Level1) +{ + SubCommandStat cmdStat; + string defaultName = "/data/storage/el2/base/cache/perf_stat.txt"; +#if defined(is_pc) && is_pc + EXPECT_EQ(cmdStat.outputFilename_, defaultName); + cmdStat.controlCmd_ = CONTROL_CMD_PREPARE; + cmdStat.CheckOutPutFile(); + char* outputPathEnv = std::getenv("TMPDIR"); + if (outputPathEnv != nullptr && strlen(outputPathEnv) > 0) { + string outputFilename = outputPathEnv; + std::string fileName = StringEndsWith(outputFilename, "/") ? "perf_stat.txt" : "/perf_stat.txt"; + outputFilename += fileName; + EXPECT_EQ(cmdStat.outputFilename_, outputFilename); + } else { + EXPECT_EQ(cmdStat.outputFilename_, defaultName); + } +#endif +} } // namespace HiPerf } // namespace Developtools } // namespace OHOS