From b5ef87ae82c208589d839ef89bf3a191b435e289 Mon Sep 17 00:00:00 2001 From: Martin Stjernholm Date: Mon, 11 Apr 2022 19:58:23 +0100 Subject: [PATCH] Add an argument to `cmd pm dump-profiles` to send --dump-classes-and-methods to profman. Test: adb root adb shell kill -SIGUSR1 '$(pidof com.android.systemui)' && \ sleep 1 && \ adb shell pm compile -m speed-profile com.android.systemui adb unroot adb shell pm dump-profiles --dump-classes-and-methods \ com.android.systemui && \ adb pull data/misc/profman/com.android.systemui-primary.prof.txt Check that the output is the same as: adb root && adb shell profman --dump-classes-and-methods \ --reference-profile-file=data/misc/profiles/ref/com.android.systemui/primary.prof \ --profile-file=data/misc/profiles/cur/0/com.android.systemui/primary.prof \ --apk=system_ext/priv-app/SystemUI/SystemUI.apk Test: adb shell pm dump-profiles \ com.android.systemui && \ adb pull data/misc/profman/com.android.systemui-primary.prof.txt Check that the output is in the usual `profman --dump-only` format Bug: 198506529 Change-Id: I2559822fcc3ad32fe4b7b6ac2faa91e3c3ab6c8e --- .../android/content/pm/IPackageManager.aidl | 8 ++++++- .../java/com/android/server/pm/Installer.java | 9 +++++-- .../server/pm/PackageManagerService.java | 4 ++-- .../server/pm/PackageManagerShellCommand.java | 24 ++++++++++++++++--- .../server/pm/dex/ArtManagerService.java | 5 ++-- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index ca7d77b2c44a3..54d57a1b24d93 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -571,8 +571,14 @@ interface IPackageManager { /** * Ask the package manager to dump profiles associated with a package. + * + * @param packageName The name of the package to dump. + * @param dumpClassesAndMethods If false, pass {@code --dump-only} to profman to dump the + * profile in a human readable form intended for debugging. If true, pass + * {@code --dump-classes-and-methods} to profman to dump a sorted list of classes and methods + * in a human readable form that is valid input for {@code profman --create-profile-from}. */ - void dumpProfiles(String packageName); + void dumpProfiles(String packageName, boolean dumpClassesAndMethods); void forceDexOpt(String packageName); diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index 2a66e026438a1..320b06f6dc3e0 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -629,12 +629,17 @@ public class Installer extends SystemService { } } - public boolean dumpProfiles(int uid, String packageName, String profileName, String codePath) + /** + * Dumps profiles associated with a package in a human readable format. + */ + public boolean dumpProfiles(int uid, String packageName, String profileName, String codePath, + boolean dumpClassesAndMethods) throws InstallerException { if (!checkBeforeRemote()) return false; BlockGuard.getVmPolicy().onPathAccess(codePath); try { - return mInstalld.dumpProfiles(uid, packageName, profileName, codePath); + return mInstalld.dumpProfiles(uid, packageName, profileName, codePath, + dumpClassesAndMethods); } catch (Exception e) { throw InstallerException.from(e); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index ffd924edc7d82..7fd28f678aedd 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4665,7 +4665,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService } @Override - public void dumpProfiles(String packageName) { + public void dumpProfiles(String packageName, boolean dumpClassesAndMethods) { /* Only the shell, root, or the app user should be able to dump profiles. */ final int callingUid = Binder.getCallingUid(); final Computer snapshot = snapshotComputer(); @@ -4683,7 +4683,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService synchronized (mInstallLock) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); - mArtManagerService.dumpProfiles(pkg); + mArtManagerService.dumpProfiles(pkg, dumpClassesAndMethods); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 7b06593324121..78a600e34daec 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -1994,8 +1994,23 @@ class PackageManagerShellCommand extends ShellCommand { } private int runDumpProfiles() throws RemoteException { + final PrintWriter pw = getOutPrintWriter(); + boolean dumpClassesAndMethods = false; + + String opt; + while ((opt = getNextOption()) != null) { + switch (opt) { + case "--dump-classes-and-methods": + dumpClassesAndMethods = true; + break; + default: + pw.println("Error: Unknown option: " + opt); + return 1; + } + } + String packageName = getNextArg(); - mInterface.dumpProfiles(packageName); + mInterface.dumpProfiles(packageName, dumpClassesAndMethods); return 0; } @@ -4164,9 +4179,12 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE"); pw.println(" Reconciles the package secondary dex files with the generated oat files."); pw.println(""); - pw.println(" dump-profiles TARGET-PACKAGE"); + pw.println(" dump-profiles [--dump-classes-and-methods] TARGET-PACKAGE"); pw.println(" Dumps method/class profile files to"); - pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + "TARGET-PACKAGE.txt"); + pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + + "TARGET-PACKAGE-primary.prof.txt."); + pw.println(" --dump-classes-and-methods: passed along to the profman binary to"); + pw.println(" switch to the format used by 'profman --create-profile-from'."); pw.println(""); pw.println(" snapshot-profile TARGET-PACKAGE [--code-path path]"); pw.println(" Take a snapshot of the package profiles to"); diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java index 4fae6b8e12715..0e46b0f42a91e 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -465,14 +465,15 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { /** * Dumps the profiles for the given package. */ - public void dumpProfiles(AndroidPackage pkg) { + public void dumpProfiles(AndroidPackage pkg, boolean dumpClassesAndMethods) { final int sharedGid = UserHandle.getSharedAppGid(pkg.getUid()); try { ArrayMap packageProfileNames = getPackageProfileNames(pkg); for (int i = packageProfileNames.size() - 1; i >= 0; i--) { String codePath = packageProfileNames.keyAt(i); String profileName = packageProfileNames.valueAt(i); - mInstaller.dumpProfiles(sharedGid, pkg.getPackageName(), profileName, codePath); + mInstaller.dumpProfiles(sharedGid, pkg.getPackageName(), profileName, codePath, + dumpClassesAndMethods); } } catch (InstallerException e) { Slog.w(TAG, "Failed to dump profiles", e);