Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit caeff8d6 authored by Mythri Alle's avatar Mythri Alle Committed by Automerger Merge Worker
Browse files

Merge "Extend am profile command to also collect lowoverhead traces." into...

Merge "Extend am profile command to also collect lowoverhead traces." into main am: c92361f4 am: 6792e492

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/3287283



Change-Id: Ic04f4aa0ea0c0046f7f485edcb6fe869cb0c928c
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 29f95c9e 6792e492
Loading
Loading
Loading
Loading
+32 −9
Original line number Diff line number Diff line
@@ -6995,21 +6995,44 @@ public final class ActivityThread extends ClientTransactionHandler

    final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
        if (start) {
            try {
            switch (profileType) {
                case ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD:
                    if (!com.android.art.flags.Flags.alwaysEnableProfileCode()) {
                        Slog.w(TAG, "Low overhead tracing feature is not enabled");
                        break;
                    }
                    VMDebug.startLowOverheadTrace();
                    break;
                default:
                    try {
                        mProfiler.setProfiler(profilerInfo);
                        mProfiler.startProfiling();
                        break;
                }
                    } catch (RuntimeException e) {
                        Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
                                + " -- can the process access this path?");
                    } finally {
                        profilerInfo.closeFd();
                    }
            }
        } else {
            switch (profileType) {
                case ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD:
                    if (!com.android.art.flags.Flags.alwaysEnableProfileCode()) {
                        if (profilerInfo != null) {
                            profilerInfo.closeFd();
                        }
                        Slog.w(TAG, "Low overhead tracing feature is not enabled");
                        break;
                    }
                    if (profilerInfo != null) {
                        FileDescriptor fd = profilerInfo.profileFd.getFileDescriptor();
                        VMDebug.TraceDestination dst =
                                VMDebug.TraceDestination.fromFileDescriptor(fd);
                        VMDebug.dumpLowOverheadTrace(dst);
                    }
                    VMDebug.stopLowOverheadTrace();
                    break;
                default:
                    mProfiler.stopProfiling();
                    break;
+6 −0
Original line number Diff line number Diff line
@@ -32,6 +32,12 @@ import java.util.Objects;
 * {@hide}
 */
public class ProfilerInfo implements Parcelable {
    // Regular profiling which provides different modes of profiling at some performance cost.
    public static final int PROFILE_TYPE_REGULAR = 0;

    // Low overhead profiling that captures a simple sliding window of past events.
    public static final int PROFILE_TYPE_LOW_OVERHEAD = 1;

    // Version of the profiler output
    public static final int OUTPUT_VERSION_DEFAULT = 1;
    // CLOCK_TYPE_DEFAULT chooses the default used by ART. ART uses CLOCK_TYPE_DUAL by default (see
+7 −4
Original line number Diff line number Diff line
@@ -7553,7 +7553,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo,
            ApplicationInfo sdkSandboxClientApp) {
            ApplicationInfo sdkSandboxClientApp, int profileType) {
        synchronized (mAppProfiler.mProfilerLock) {
            if (!Build.IS_DEBUGGABLE) {
                boolean isAppDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
@@ -7569,7 +7569,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                            + "and not profileable by shell: " + app.packageName);
                }
            }
            mAppProfiler.setProfileAppLPf(processName, profilerInfo);
            mAppProfiler.setProfileAppLPf(processName, profilerInfo, profileType);
        }
    }
@@ -15847,7 +15847,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
        }
        if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
        if (start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR
                && (profilerInfo == null || profilerInfo.profileFd == null)) {
            throw new IllegalArgumentException("null profile info or fd");
        }
@@ -17490,7 +17491,9 @@ public class ActivityManagerService extends IActivityManager.Stub
                    }
                    if (profilerInfo != null) {
                        setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, null);
                        // We only support normal method tracing along with app startup for now.
                        setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo,
                                null, /*profileType= */ ProfilerInfo.PROFILE_TYPE_REGULAR);
                    }
                    wmLock.notify();
                }
+19 −2
Original line number Diff line number Diff line
@@ -1155,7 +1155,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
        String profileFile = null;
        boolean start = false;
        int userId = UserHandle.USER_CURRENT;
        int profileType = 0;
        int profileType = ProfilerInfo.PROFILE_TYPE_REGULAR;
        mSamplingInterval = 0;
        mStreaming = false;
        mClockType = ProfilerInfo.CLOCK_TYPE_DEFAULT;
@@ -1197,6 +1197,18 @@ final class ActivityManagerShellCommand extends ShellCommand {
                }
            }
            process = getNextArgRequired();
        } else if ("lowoverhead".equals(cmd)) {
            // This is an experimental low overhead profiling.
            profileType = ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD;
            cmd = getNextArgRequired();
            if ("start".equals(cmd)) {
                start = true;
            } else if ("stop".equals(cmd)) {
                start = false;
            } else {
                throw new IllegalArgumentException("Profile command not valid");
            }
            process = getNextArgRequired();
        } else {
            // Compatibility with old syntax: process is specified first.
            process = cmd;
@@ -1216,7 +1228,12 @@ final class ActivityManagerShellCommand extends ShellCommand {
        ParcelFileDescriptor fd = null;
        ProfilerInfo profilerInfo = null;

        if (start) {
        // For regular method tracing  profileFile should be provided with the start command. For
        // low overhead method tracing the profileFile is optional and provided with the stop
        // command.
        if ((start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR)
                || (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD
                  && !start && getRemainingArgsCount() > 0)) {
            profileFile = getNextArgRequired();
            fd = openFileForSystem(profileFile, "w");
            if (fd == null) {
+47 −28
Original line number Diff line number Diff line
@@ -1992,7 +1992,7 @@ public class AppProfiler {
    }

    @GuardedBy("mProfilerLock")
    private void stopProfilerLPf(ProcessRecord proc, int profileType) {
    private void stopProfilerLPf(ProcessRecord proc, ProfilerInfo profilerInfo, int profileType) {
        if (proc == null || proc == mProfileData.getProfileProc()) {
            proc = mProfileData.getProfileProc();
            profileType = mProfileType;
@@ -2006,7 +2006,7 @@ public class AppProfiler {
            return;
        }
        try {
            thread.profilerControl(false, null, profileType);
            thread.profilerControl(false, profilerInfo, profileType);
        } catch (RemoteException e) {
            throw new IllegalStateException("Process disappeared");
        }
@@ -2041,19 +2041,27 @@ public class AppProfiler {
            ProfilerInfo profilerInfo, int profileType) {
        try {
            if (start) {
                stopProfilerLPf(null, 0);
                boolean needsFile = (profileType == ProfilerInfo.PROFILE_TYPE_REGULAR);
                stopProfilerLPf(null, null, 0);
                mService.setProfileApp(proc.info, proc.processName, profilerInfo,
                        proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null);
                        proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null, profileType);
                mProfileData.setProfileProc(proc);
                mProfileType = profileType;
                ParcelFileDescriptor fd = profilerInfo.profileFd;

                ParcelFileDescriptor fd = null;
                if (needsFile) {
                    fd = profilerInfo.profileFd;
                    try {
                        fd = fd.dup();
                    } catch (IOException e) {
                        fd = null;
                    }
                    profilerInfo.profileFd = fd;
                }

                proc.mProfile.getThread().profilerControl(start, profilerInfo, profileType);

                if (needsFile) {
                    fd = null;
                    try {
                        mProfileData.getProfilerInfo().profileFd.close();
@@ -2068,14 +2076,23 @@ public class AppProfiler {
                        //       whole ProfilerInfo instance is passed down!
                        profilerInfo = null;
                    }
                }
            } else {
                stopProfilerLPf(proc, profileType);
                boolean mayNeedFile = (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD);
                if (profilerInfo != null && profilerInfo.profileFd != null) {
                    ParcelFileDescriptor fd = profilerInfo.profileFd;
                    try {
                        profilerInfo.profileFd.close();
                        if (mayNeedFile) {
                            fd = fd.dup();
                        } else {
                            fd.close();
                        }
                    } catch (IOException e) {
                        fd = null;
                    }
                    profilerInfo.profileFd = fd;
                }
                stopProfilerLPf(proc, profilerInfo, profileType);
            }

            return true;
@@ -2092,7 +2109,7 @@ public class AppProfiler {
    }

    @GuardedBy("mProfilerLock")
    void setProfileAppLPf(String processName, ProfilerInfo profilerInfo) {
    void setProfileAppLPf(String processName, ProfilerInfo profilerInfo, int profileType) {
        mProfileData.setProfileApp(processName);

        if (mProfileData.getProfilerInfo() != null) {
@@ -2103,8 +2120,10 @@ public class AppProfiler {
                }
            }
        }
        if (profilerInfo != null) {
            mProfileData.setProfilerInfo(new ProfilerInfo(profilerInfo));
        mProfileType = 0;
        }
        mProfileType = profileType;
    }

    @GuardedBy("mProfilerLock")