diff options
Diffstat (limited to 'simpleperf/app_api/cpp/simpleperf.cpp')
-rw-r--r-- | simpleperf/app_api/cpp/simpleperf.cpp | 94 |
1 files changed, 23 insertions, 71 deletions
diff --git a/simpleperf/app_api/cpp/simpleperf.cpp b/simpleperf/app_api/cpp/simpleperf.cpp index 54b331a3..23bb4fb5 100644 --- a/simpleperf/app_api/cpp/simpleperf.cpp +++ b/simpleperf/app_api/cpp/simpleperf.cpp @@ -188,7 +188,6 @@ class ProfileSessionImpl { pid_t simpleperf_pid_ = -1; int control_fd_ = -1; int reply_fd_ = -1; - bool trace_offcpu_ = false; }; ProfileSessionImpl::~ProfileSessionImpl() { @@ -205,11 +204,6 @@ void ProfileSessionImpl::StartRecording(const std::vector<std::string> &args) { if (state_ != NOT_YET_STARTED) { Abort("startRecording: session in wrong state %d", state_); } - for (const auto& arg : args) { - if (arg == "--trace-offcpu") { - trace_offcpu_ = true; - } - } std::string simpleperf_path = FindSimpleperf(); CheckIfPerfEnabled(); CreateSimpleperfDataDir(); @@ -222,9 +216,6 @@ void ProfileSessionImpl::PauseRecording() { if (state_ != STARTED) { Abort("pauseRecording: session in wrong state %d", state_); } - if (trace_offcpu_) { - Abort("--trace-offcpu doesn't work well with pause/resume recording"); - } SendCmd("pause"); state_ = PAUSED; } @@ -279,61 +270,6 @@ static bool IsExecutableFile(const std::string& path) { return false; } -static std::string ReadFile(FILE* fp) { - std::string s; - if (fp == nullptr) { - return s; - } - char buf[200]; - while (true) { - ssize_t n = fread(buf, 1, sizeof(buf), fp); - if (n <= 0) { - break; - } - s.insert(s.end(), buf, buf + n); - } - fclose(fp); - return s; -} - -static bool RunCmd(std::vector<const char*> args, std::string* stdout) { - int stdout_fd[2]; - if (pipe(stdout_fd) != 0) { - return false; - } - args.push_back(nullptr); - // Fork handlers (like gsl_library_close) may hang in a multi-thread environment. - // So we use vfork instead of fork to avoid calling them. - int pid = vfork(); - if (pid == -1) { - return false; - } - if (pid == 0) { - // child process - close(stdout_fd[0]); - dup2(stdout_fd[1], 1); - close(stdout_fd[1]); - execvp(const_cast<char*>(args[0]), const_cast<char**>(args.data())); - _exit(1); - } - // parent process - close(stdout_fd[1]); - int status; - pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); - if (result == -1) { - Abort("failed to call waitpid: %s", strerror(errno)); - } - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - return false; - } - if (stdout == nullptr) { - close(stdout_fd[0]); - } else { - *stdout = ReadFile(fdopen(stdout_fd[0], "r")); - } - return true; -} - std::string ProfileSessionImpl::FindSimpleperf() { // 1. Try /data/local/tmp/simpleperf first. Probably it's newer than /system/bin/simpleperf. std::string simpleperf_path = FindSimpleperfInTempDir(); @@ -356,21 +292,38 @@ std::string ProfileSessionImpl::FindSimpleperfInTempDir() { } // Copy it to app_dir to execute it. const std::string to_path = app_data_dir_ + "/simpleperf"; - if (!RunCmd({"/system/bin/cp", path.c_str(), to_path.c_str()}, nullptr)) { + const std::string copy_cmd = "cp " + path + " " + to_path; + if (system(copy_cmd.c_str()) != 0) { return ""; } + const std::string test_cmd = to_path; // For apps with target sdk >= 29, executing app data file isn't allowed. So test executing it. - if (!RunCmd({to_path.c_str()}, nullptr)) { + if (system(test_cmd.c_str()) != 0) { return ""; } return to_path; } -void ProfileSessionImpl::CheckIfPerfEnabled() { +static std::string ReadFile(FILE* fp) { std::string s; - if (!RunCmd({"/system/bin/getprop", "security.perf_harden"}, &s)) { + char buf[200]; + while (true) { + ssize_t n = fread(buf, 1, sizeof(buf), fp); + if (n <= 0) { + break; + } + s.insert(s.end(), buf, buf + n); + } + return s; +} + +void ProfileSessionImpl::CheckIfPerfEnabled() { + FILE* fp = popen("/system/bin/getprop security.perf_harden", "re"); + if (fp == nullptr) { return; // Omit check if getprop doesn't exist. } + std::string s = ReadFile(fp); + pclose(fp); if (!s.empty() && s[0] == '1') { Abort("linux perf events aren't enabled on the device. Please run api_profiler.py."); } @@ -413,9 +366,7 @@ void ProfileSessionImpl::CreateSimpleperfProcess(const std::string &simpleperf_p argv[args.size()] = nullptr; // 3. Start simpleperf process. - // Fork handlers (like gsl_library_close) may hang in a multi-thread environment. - // So we use vfork instead of fork to avoid calling them. - int pid = vfork(); + int pid = fork(); if (pid == -1) { Abort("failed to fork: %s", strerror(errno)); } @@ -464,6 +415,7 @@ ProfileSession::ProfileSession() { Abort("failed to open /proc/self/cmdline: %s", strerror(errno)); } std::string s = ReadFile(fp); + fclose(fp); for (int i = 0; i < s.size(); i++) { if (s[i] == '\0') { s = s.substr(0, i); |