diff --git a/BUILD.gn b/BUILD.gn index 677648e86fdddb8dfbda3f9dc42a699559d2f8a1..c016b30be592ff6cf5aa42f67d09d1d31b035af9 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_sandbox_log_path_mapping) { + defines += [ "is_sandbox_mapping=${hiperf_sandbox_log_path_mapping}" ] + } 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_sandbox_log_path_mapping) { + defines += [ "is_sandbox_mapping=${hiperf_sandbox_log_path_mapping}" ] + } } 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..12bbd79b4103c04b7a740ef61dba562df6530264 100644 --- a/bundle.json +++ b/bundle.json @@ -12,6 +12,9 @@ "component": { "name": "hiperf", "subsystem": "developtools", + "features": [ + "hiperf_sandbox_log_path_mapping" + ], "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..6393d17b0ea5058af26f4fd38c7a26385b0885f4 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_sandbox_log_path_mapping = 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 dfdc2581660061ad033e04f95b104625e0b03930..fb79c84db75f7998b2eb112d0fc85d6b479ccc41 100644 --- a/include/subcommand_record.h +++ b/include/subcommand_record.h @@ -181,7 +181,11 @@ public: " --data-limit \n" " Stop recording after SIZE bytes of records. Default is unlimited.\n" " -o \n" +#if defined(is_sandbox_mapping) && is_sandbox_mapping + " Set output file name, default is " + GetDefaultPathByEnv("perf.data") + ".\n" +#else " Set output file name, default is /data/local/tmp/perf.data.\n" +#endif " -z\n" " Compress record data.\n" " --restart\n" @@ -260,7 +264,11 @@ private: int cmdlinesSize_ = DEFAULT_SAVED_CMDLINES_SIZE; int oldCmdlinesSize_ = 0; std::vector symbolDir_ = {}; +#if defined(is_sandbox_mapping) && is_sandbox_mapping + std::string outputFilename_ = GetDefaultPathByEnv("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 b229a8865edad99c40e140252ce6b566304b678c..83ba5f1f82943ad734f297951af9ce0b44b1cb6b 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_sandbox_mapping) && is_sandbox_mapping + " Set output file name, default is " + GetDefaultPathByEnv("perf_stat.txt") + ".\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 001cec2f37679f4d0fc3d3b24be7fa3aa65efb0c..3191e2885778b830b26e61288d26cf89eb874647 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 + +std::string GetDefaultPathByEnv(const std::string fileType); } // namespace HiPerf } // namespace Developtools } // namespace OHOS diff --git a/src/debug_logger.cpp b/src/debug_logger.cpp index 8cfe4cad0b8f2519c654450a4377d60e6593d731..9e3362d308d6f35f49d6647ef2956aa4dab05e1e 100644 --- a/src/debug_logger.cpp +++ b/src/debug_logger.cpp @@ -19,12 +19,18 @@ #if defined(is_ohos) && is_ohos #include "hiperf_hilog.h" #endif +#include "utilities.h" namespace OHOS { namespace Developtools { namespace HiPerf { -DebugLogger::DebugLogger() : timeStamp_(std::chrono::steady_clock::now()), logPath_(DEFAULT_LOG_PATH) +DebugLogger::DebugLogger() : timeStamp_(std::chrono::steady_clock::now()) { +#if defined(is_sandbox_mapping) && is_sandbox_mapping + logPath_ = GetDefaultPathByEnv("hiperf_log.txt"); +#else + logPath_ = "/data/local/tmp/hiperf_log.txt"; +#endif OpenLog(); } diff --git a/src/subcommand_record.cpp b/src/subcommand_record.cpp index e0ed4e2a31342ed482b6e83845494f198ab6bbdf..6ac6bd24e185ca3236e5d6285421e35f7d950d9a 100644 --- a/src/subcommand_record.cpp +++ b/src/subcommand_record.cpp @@ -2078,7 +2078,6 @@ bool SubCommandRecord::CreateInitRecordFile(const bool compressData) CHECK_TRUE(fileWriter_->WriteAttrAndId(perfEvents_.GetAttrWithId(), isSpe_), false, 0, ""); CHECK_TRUE(AddFeatureRecordFile(), false, 0, ""); - HLOGD("create new record file %s", outputFilename_.c_str()); return true; } @@ -2101,7 +2100,11 @@ bool SubCommandRecord::PostProcessRecordFile() fileWriter_.reset(); if (!CreateInitRecordFile(compressData_)) { // create again +#if defined(is_sandbox_mapping) && is_sandbox_mapping + HLOGEP("Fail to open data file"); +#else HLOGEP("Fail to open data file %s ", outputFilename_.c_str()); +#endif return false; } diff --git a/src/subcommand_stat.cpp b/src/subcommand_stat.cpp index 2ff131614181de0e459598d2ebabd196a16d9ba2..bfbdc9eb146ff7fb815d30505579894355ab7b09 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_sandbox_mapping) && is_sandbox_mapping +const std::string DEFAULT_STAT_FILE = GetDefaultPathByEnv("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_; @@ -912,7 +916,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; diff --git a/src/utilities.cpp b/src/utilities.cpp index b5e8e65faaabbfcb8c65d4655b7438f02fb516ba..9de04fff0d58821141a89c37582c9807f967216f 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -25,6 +25,10 @@ #include #endif +#if defined(is_ohos) && is_ohos +#include +#endif + #ifdef CONFIG_HAS_CCM #include "config_policy_utils.h" #endif @@ -1078,6 +1082,58 @@ void AgeHiperflogFiles() } #endif } + +bool IsHiShellLabel() +{ +#if defined(is_sandbox_mapping) && is_sandbox_mapping + pid_t ppid = syscall(SYS_getppid); + char buf[DEFAULT_STRING_BUF_SIZE] = ""; + if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "/proc/%d/attr/current", ppid) < 0) { + HLOGE("get buf failed, pid is %d", ppid); + return false; + } + + const char* attrName = "security.selinux"; + ssize_t attrSize = getxattr(buf, attrName, nullptr, 0); + if (attrSize == 0 || attrSize == - 1) { + return false; + } + char* attrValue = new(std::nothrow) char[attrSize]; + if (attrValue == nullptr) { + return false; + } + if (getxattr(buf, attrName, attrValue, attrSize) == -1) { + delete []attrValue; + return false; + } + std::string label(attrValue, attrSize - 1); + delete []attrValue; + return label == "u:r:hishell_hap:s0"; +#else + return false; +#endif +} + +std::string GetDefaultPathByEnv(const std::string fileType) +{ + std::string outputFilename = "/data/local/tmp/" + fileType; +#if defined(is_sandbox_mapping) && is_sandbox_mapping + if (IsHiShellLabel()) { + char* outputPathEnv = std::getenv("TMPDIR"); + if (outputPathEnv != nullptr && strlen(outputPathEnv) > 0) { + std::string tmpFilename = outputPathEnv; + std::string fileName = StringEndsWith(outputFilename, "/") ? fileType : "/" + fileType; + tmpFilename += fileName; + outputFilename = CanonicalizeSpecPath(tmpFilename.c_str()); + HIPERF_HILOGI(MODULE_DEFAULT, "get TMPDIR env success"); + } else { + outputFilename = "/storage/Users/currentUser/" + fileType; + HIPERF_HILOGE(MODULE_DEFAULT, "get TMPDIR env failed"); + } + } +#endif + return outputFilename; +} } // namespace HiPerf } // namespace Developtools } // namespace OHOS diff --git a/test/BUILD.gn b/test/BUILD.gn index aabe9d065cf4bff5c576209eca73f44f7eaa59fc..518b0a4d5f8e3ef90971470a8f790e3a4892f195 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -113,6 +113,10 @@ ohos_unittest("hiperf_unittest") { "CONFIG_HAS_CCM", ] + if (hiperf_sandbox_log_path_mapping) { + defines += [ "is_sandbox_mapping=${hiperf_sandbox_log_path_mapping}" ] + } + 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..b4eb1e387335081a3e3dcfd47ba363ed4ed019a7 100644 --- a/test/unittest/common/native/subcommand_record_test.cpp +++ b/test/unittest/common/native/subcommand_record_test.cpp @@ -2544,6 +2544,13 @@ 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/local/tmp/perf.data"; + EXPECT_EQ(cmd.outputFilename_, defaultName); +} } // 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..8faced527d70cbbdc7f4c9eb6d54cd52cee886aa 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,13 @@ 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) +{ + std::string defaultName = "/data/local/tmp/perf_stat.txt"; + std::string outputPath = GetDefaultPathByEnv("perf_stat.txt"); + EXPECT_EQ(defaultName, outputPath); +} } // namespace HiPerf } // namespace Developtools } // namespace OHOS