diff options
author | Yabin Cui <yabinc@google.com> | 2021-05-14 21:17:26 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-05-14 21:17:26 +0000 |
commit | 1d0a3a5fc444965246a5439f90f43ea370f76ae7 (patch) | |
tree | 879567725f4a92c93e0223b43bf9de28d6d35db1 | |
parent | 41d2d1781a2a248a63b9fd9eb693b1336d6edc10 (diff) | |
parent | ea752c44ab12c0deeb0f951ea2556e356c73e959 (diff) | |
download | extras-1d0a3a5fc444965246a5439f90f43ea370f76ae7.tar.gz |
Merge "simpleperf: add --show-app-type in simpleperf_app_runner." am: b233aea6a9 am: ea752c44ab
Original change: https://android-review.googlesource.com/c/platform/system/extras/+/1706288
Change-Id: I25208c3f63f6cb939230f87bab0d4db38acaf110
-rw-r--r-- | simpleperf/cmd_record.cpp | 3 | ||||
-rw-r--r-- | simpleperf/cmd_record_test.cpp | 3 | ||||
-rw-r--r-- | simpleperf/environment.cpp | 55 | ||||
-rw-r--r-- | simpleperf/environment.h | 1 | ||||
-rw-r--r-- | simpleperf/environment_test.cpp | 7 | ||||
-rw-r--r-- | simpleperf/simpleperf_app_runner/simpleperf_app_runner.cpp | 28 |
6 files changed, 78 insertions, 19 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp index 18e4888c..9d9abb61 100644 --- a/simpleperf/cmd_record.cpp +++ b/simpleperf/cmd_record.cpp @@ -1918,6 +1918,9 @@ bool RecordCommand::DumpMetaInfoFeature(bool kernel_symbols_available) { info_map["android_build_type"] = android::base::GetProperty("ro.build.type", ""); if (!app_package_name_.empty()) { info_map["app_package_name"] = app_package_name_; + if (IsRoot()) { + info_map["app_type"] = GetAppType(app_package_name_); + } } if (event_selection_set_.HasAuxTrace()) { // used by --exclude-perf in cmd_inject.cpp diff --git a/simpleperf/cmd_record_test.cpp b/simpleperf/cmd_record_test.cpp index c59641ca..869c747f 100644 --- a/simpleperf/cmd_record_test.cpp +++ b/simpleperf/cmd_record_test.cpp @@ -754,8 +754,7 @@ TEST(record_cmd, app_option_for_debuggable_app) { SetRunInAppToolForTesting(true, false); TestRecordingApps("com.android.simpleperf.debuggable", "debuggable"); SetRunInAppToolForTesting(false, true); - // Although the app is actually debuggable, we profile the app using simpleperf_app_runner. - TestRecordingApps("com.android.simpleperf.debuggable", "profileable"); + TestRecordingApps("com.android.simpleperf.debuggable", "debuggable"); } TEST(record_cmd, app_option_for_profileable_app) { diff --git a/simpleperf/environment.cpp b/simpleperf/environment.cpp index 4fe908fa..4c960350 100644 --- a/simpleperf/environment.cpp +++ b/simpleperf/environment.cpp @@ -530,9 +530,10 @@ std::set<pid_t> WaitForAppProcesses(const std::string& package_name) { namespace { -bool IsAppDebuggable(const std::string& user_id, const std::string& package_name) { - return Workload::RunCmd( - {"run-as", package_name, "--user", user_id, "echo", ">/dev/null", "2>/dev/null"}, false); +bool IsAppDebuggable(int user_id, const std::string& package_name) { + return Workload::RunCmd({"run-as", package_name, "--user", std::to_string(user_id), "echo", + ">/dev/null", "2>/dev/null"}, + false); } class InAppRunner { @@ -696,10 +697,6 @@ class RunAs : public InAppRunner { }; bool RunAs::Prepare() { - // Test if run-as can access the package. - if (!IsAppDebuggable(user_id_, package_name_)) { - return false; - } // run-as can't run /data/local/tmp/simpleperf directly. So copy simpleperf binary if needed. if (!android::base::Readlink("/proc/self/exe", &simpleperf_path_)) { PLOG(ERROR) << "ReadLink failed"; @@ -722,8 +719,12 @@ bool RunAs::Prepare() { class SimpleperfAppRunner : public InAppRunner { public: - SimpleperfAppRunner(int user_id, const std::string& package_name) - : InAppRunner(user_id, package_name) {} + SimpleperfAppRunner(int user_id, const std::string& package_name, const std::string app_type) + : InAppRunner(user_id, package_name) { + // On Android < S, the app type is unknown before running simpleperf_app_runner. Assume it's + // profileable. + app_type_ = app_type == "unknown" ? "profileable" : app_type; + } bool Prepare() override { return GetAndroidVersion() >= kAndroidVersionQ; } protected: @@ -736,10 +737,12 @@ class SimpleperfAppRunner : public InAppRunner { args.emplace_back(cmd); if (cmd == "record" && GetAndroidVersion() >= kAndroidVersionS) { args.emplace_back("--add-meta-info"); - args.emplace_back("app_type=profileable"); + args.emplace_back("app_type=" + app_type_); } return args; } + + std::string app_type_; }; } // namespace @@ -766,21 +769,45 @@ static int GetCurrentUserId() { return 0; } +std::string GetAppType(const std::string& app_package_name) { + if (GetAndroidVersion() < kAndroidVersionS) { + return "unknown"; + } + std::string cmd = "simpleperf_app_runner " + app_package_name + " --show-app-type"; + std::unique_ptr<FILE, decltype(&pclose)> fp(popen(cmd.c_str(), "re"), pclose); + if (fp) { + char buf[128]; + if (fgets(buf, sizeof(buf), fp.get()) != nullptr) { + return android::base::Trim(buf); + } + } + // Can't get app_type. It means the app doesn't exist. + return "not_exist"; +} + bool RunInAppContext(const std::string& app_package_name, const std::string& cmd, const std::vector<std::string>& args, size_t workload_args_size, const std::string& output_filepath, bool need_tracepoint_events) { int user_id = GetCurrentUserId(); std::unique_ptr<InAppRunner> in_app_runner; - if (allow_run_as) { + + std::string app_type = GetAppType(app_package_name); + if (app_type == "unknown" && IsAppDebuggable(user_id, app_package_name)) { + app_type = "debuggable"; + } + + if (allow_run_as && app_type == "debuggable") { in_app_runner.reset(new RunAs(user_id, app_package_name)); if (!in_app_runner->Prepare()) { in_app_runner = nullptr; } } if (!in_app_runner && allow_simpleperf_app_runner) { - in_app_runner.reset(new SimpleperfAppRunner(user_id, app_package_name)); - if (!in_app_runner->Prepare()) { - in_app_runner = nullptr; + if (app_type == "debuggable" || app_type == "profileable" || app_type == "unknown") { + in_app_runner.reset(new SimpleperfAppRunner(user_id, app_package_name, app_type)); + if (!in_app_runner->Prepare()) { + in_app_runner = nullptr; + } } } if (!in_app_runner) { diff --git a/simpleperf/environment.h b/simpleperf/environment.h index 665a7c53..180b98c3 100644 --- a/simpleperf/environment.h +++ b/simpleperf/environment.h @@ -94,6 +94,7 @@ void SetRunInAppToolForTesting(bool run_as, bool simpleperf_app_runner); // for bool RunInAppContext(const std::string& app_package_name, const std::string& cmd, const std::vector<std::string>& args, size_t workload_args_size, const std::string& output_filepath, bool need_tracepoint_events); +std::string GetAppType(const std::string& app_package_name); void AllowMoreOpenedFiles(); diff --git a/simpleperf/environment_test.cpp b/simpleperf/environment_test.cpp index 596b632a..a95caca8 100644 --- a/simpleperf/environment_test.cpp +++ b/simpleperf/environment_test.cpp @@ -129,3 +129,10 @@ TEST(environment, GetProcessUid) { ASSERT_TRUE(uid.has_value()); ASSERT_EQ(uid.value(), getuid()); } + +TEST(environment, GetAppType) { + TEST_REQUIRE_APPS(); + ASSERT_EQ(GetAppType("com.android.simpleperf.debuggable"), "debuggable"); + ASSERT_EQ(GetAppType("com.android.simpleperf.profileable"), "profileable"); + ASSERT_EQ(GetAppType("com.android.simpleperf.app_not_exist"), "not_exist"); +} diff --git a/simpleperf/simpleperf_app_runner/simpleperf_app_runner.cpp b/simpleperf/simpleperf_app_runner/simpleperf_app_runner.cpp index 20329d0d..f3e6b4b5 100644 --- a/simpleperf/simpleperf_app_runner/simpleperf_app_runner.cpp +++ b/simpleperf/simpleperf_app_runner/simpleperf_app_runner.cpp @@ -164,9 +164,16 @@ static void CheckSimpleperfArguments(std::string_view cmd_name, char** args) { int main(int argc, char* argv[]) { if (argc < 3) { - error(1, 0, - "usage: simpleperf_app_runner package_name [--user uid] simpleperf_cmd " - "simpleperf_cmd_args..."); + fprintf( + stderr, + // clang-format off +"Usage: simpleperf_app_runner package_name [options] [simpleperf cmd simpleperf_cmd_args]\n" +"Options:\n" +"--user uid profile app process run by uid\n" +"--show-app-type show if the app is debuggable or profileable\n" + // clang-format on + ); + return 1; } int i = 1; char* pkgname = argv[i++]; @@ -177,6 +184,21 @@ int main(int argc, char* argv[]) { } i += 2; } + if (i < argc && strcmp(argv[i], "--show-app-type") == 0) { + pkg_info* info = ReadPackageInfo(pkgname); + if (info == nullptr) { + error(1, 0, "failed to find package %s", pkgname); + } + if (info->debuggable) { + printf("debuggable\n"); + } else if (info->profileable_from_shell) { + printf("profileable\n"); + } else { + printf("non_profileable\n"); + } + return 0; + } + if (i == argc) { error(1, 0, "no simpleperf command name"); } |