summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2021-05-14 21:19:54 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-05-14 21:19:54 +0000
commit31f4af9ce9c2c4cf0a9ab7706f1a5c1fb3c56302 (patch)
tree406b312bbe71e53c632a1b0fd4842f4ff1189f6d
parentc03e6f945e07efe2b98c20adb056ea4e22a4c124 (diff)
parent1d0a3a5fc444965246a5439f90f43ea370f76ae7 (diff)
downloadextras-31f4af9ce9c2c4cf0a9ab7706f1a5c1fb3c56302.tar.gz
Merge "simpleperf: add --show-app-type in simpleperf_app_runner." am: b233aea6a9 am: ea752c44ab am: 1d0a3a5fc4
Original change: https://android-review.googlesource.com/c/platform/system/extras/+/1706288 Change-Id: I8f9bcc170e9be7da62c87b48bab97b27a71091f7
-rw-r--r--simpleperf/cmd_record.cpp3
-rw-r--r--simpleperf/cmd_record_test.cpp3
-rw-r--r--simpleperf/environment.cpp55
-rw-r--r--simpleperf/environment.h1
-rw-r--r--simpleperf/environment_test.cpp7
-rw-r--r--simpleperf/simpleperf_app_runner/simpleperf_app_runner.cpp28
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");
}