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

Commit 6ffd4f9b authored by Shukang Zhou's avatar Shukang Zhou
Browse files

[Frameworks] Add an 'am' cmd option to enable streaming in profiling.

Add option '--streaming' to 'am start' and 'am profile' commands.
If the option is given, the output of method trace profiling
will be streamed into the specified file, so the output is no
longer limited by the buffer size.

Test: m -j48 test-art-host;
m -j48 ART_TEST_TRACE=true ART_TEST_TRACE_STREAM=true test-art-host;
I also tested manually. Tried all 8 combinations of
    sampling/instrumention
    streaming/non-streaming
    'am start --start-profiler' / 'am profile start'
The output files are all in expected shape.

Bug: 33300765

Change-Id: I8a5136a1c7330c8260b7c6c8da63f42a73aee275
parent 3416cc28
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -541,6 +541,7 @@ public final class ActivityThread {
        ParcelFileDescriptor profileFd;
        int samplingInterval;
        boolean autoStopProfiler;
        boolean streamingOutput;
        boolean profiling;
        boolean handlingProfiling;
        public void setProfiler(ProfilerInfo profilerInfo) {
@@ -566,6 +567,7 @@ public final class ActivityThread {
            profileFd = fd;
            samplingInterval = profilerInfo.samplingInterval;
            autoStopProfiler = profilerInfo.autoStopProfiler;
            streamingOutput = profilerInfo.streamingOutput;
        }
        public void startProfiling() {
            if (profileFd == null || profiling) {
@@ -574,7 +576,8 @@ public final class ActivityThread {
            try {
                int bufferSize = SystemProperties.getInt("debug.traceview-buffer-size-mb", 8);
                VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
                        bufferSize * 1024 * 1024, 0, samplingInterval != 0, samplingInterval);
                        bufferSize * 1024 * 1024, 0, samplingInterval != 0, samplingInterval,
                        streamingOutput);
                profiling = true;
            } catch (RuntimeException e) {
                Slog.w(TAG, "Profiling failed on path " + profileFile);
@@ -5275,6 +5278,7 @@ public final class ActivityThread {
            mProfiler.profileFd = data.initProfilerInfo.profileFd;
            mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
            mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
            mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput;
        }

        // send up app name; do this *before* waiting for debugger
+8 −1
Original line number Diff line number Diff line
@@ -39,11 +39,16 @@ public class ProfilerInfo implements Parcelable {
    /* Automatically stop the profiler when the app goes idle. */
    public final boolean autoStopProfiler;

    public ProfilerInfo(String filename, ParcelFileDescriptor fd, int interval, boolean autoStop) {
    /* Indicates whether to stream the profiling info to the out file continuously. */
    public final boolean streamingOutput;

    public ProfilerInfo(String filename, ParcelFileDescriptor fd, int interval, boolean autoStop,
                        boolean streaming) {
        profileFile = filename;
        profileFd = fd;
        samplingInterval = interval;
        autoStopProfiler = autoStop;
        streamingOutput = streaming;
    }

    public int describeContents() {
@@ -64,6 +69,7 @@ public class ProfilerInfo implements Parcelable {
        }
        out.writeInt(samplingInterval);
        out.writeInt(autoStopProfiler ? 1 : 0);
        out.writeInt(streamingOutput ? 1 : 0);
    }

    public static final Parcelable.Creator<ProfilerInfo> CREATOR =
@@ -82,5 +88,6 @@ public class ProfilerInfo implements Parcelable {
        profileFd = in.readInt() != 0 ? ParcelFileDescriptor.CREATOR.createFromParcel(in) : null;
        samplingInterval = in.readInt();
        autoStopProfiler = in.readInt() != 0;
        streamingOutput = in.readInt() != 0;
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -1119,8 +1119,8 @@ public final class Debug
     * @hide
     */
    public static void startMethodTracing(String traceName, FileDescriptor fd,
        int bufferSize, int flags) {
        VMDebug.startMethodTracing(traceName, fd, bufferSize, flags, false, 0);
        int bufferSize, int flags, boolean streamOutput) {
        VMDebug.startMethodTracing(traceName, fd, bufferSize, flags, false, 0, streamOutput);
    }

    /**
+8 −2
Original line number Diff line number Diff line
@@ -1422,6 +1422,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    ParcelFileDescriptor mProfileFd;
    int mSamplingInterval = 0;
    boolean mAutoStopProfiler = false;
    boolean mStreamingOutput = false;
    int mProfileType = 0;
    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
    String mMemWatchDumpProcName;
@@ -6560,12 +6561,14 @@ public class ActivityManagerService extends IActivityManager.Stub
            ParcelFileDescriptor profileFd = null;
            int samplingInterval = 0;
            boolean profileAutoStop = false;
            boolean profileStreamingOutput = false;
            if (mProfileApp != null && mProfileApp.equals(processName)) {
                mProfileProc = app;
                profileFile = mProfileFile;
                profileFd = mProfileFd;
                samplingInterval = mSamplingInterval;
                profileAutoStop = mAutoStopProfiler;
                profileStreamingOutput = mStreamingOutput;
            }
            boolean enableTrackAllocation = false;
            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
@@ -6595,7 +6598,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                profileFd = profileFd.dup();
            }
            ProfilerInfo profilerInfo = profileFile == null ? null
                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
                                       profileStreamingOutput);
            // We deprecated Build.SERIAL and only apps that target pre NMR1
            // SDK can see it. Since access to the serial is now behind a
@@ -12194,6 +12198,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            mProfileFd = profilerInfo.profileFd;
            mSamplingInterval = profilerInfo.samplingInterval;
            mAutoStopProfiler = profilerInfo.autoStopProfiler;
            mStreamingOutput = profilerInfo.streamingOutput;
            mProfileType = 0;
        }
    }
@@ -15172,7 +15177,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
                        + mAutoStopProfiler);
                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
                pw.println("  mProfileType=" + mProfileType);
            }
        }
@@ -22021,6 +22026,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        mProfileFile = null;
        mProfileType = 0;
        mAutoStopProfiler = false;
        mStreamingOutput = false;
        mSamplingInterval = 0;
    }
+17 −4
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
    private String mProfileFile;
    private int mSamplingInterval;
    private boolean mAutoStop;
    private boolean mStreaming;   // Streaming the profiling output to a file.
    private int mDisplayId;
    private int mStackId;

@@ -256,6 +257,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
        mProfileFile = null;
        mSamplingInterval = 0;
        mAutoStop = false;
        mStreaming = false;
        mUserId = defUser;
        mDisplayId = INVALID_DISPLAY;
        mStackId = INVALID_STACK_ID;
@@ -277,6 +279,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    mAutoStop = false;
                } else if (opt.equals("--sampling")) {
                    mSamplingInterval = Integer.parseInt(getNextArgRequired());
                } else if (opt.equals("--streaming")) {
                    mStreaming = true;
                } else if (opt.equals("-R")) {
                    mRepeat = Integer.parseInt(getNextArgRequired());
                } else if (opt.equals("-S")) {
@@ -354,7 +358,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                if (fd == null) {
                    return 1;
                }
                profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop);
                profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
                                                mStreaming);
            }

            pw.println("Starting: " + intent);
@@ -659,6 +664,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
        int userId = UserHandle.USER_CURRENT;
        int profileType = 0;
        mSamplingInterval = 0;
        mStreaming = false;

        String process = null;

@@ -672,6 +678,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    userId = UserHandle.parseUserArg(getNextArgRequired());
                } else if (opt.equals("--wall")) {
                    wall = true;
                } else if (opt.equals("--streaming")) {
                    mStreaming = true;
                } else if (opt.equals("--sampling")) {
                    mSamplingInterval = Integer.parseInt(getNextArgRequired());
                } else {
@@ -716,7 +724,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
            if (fd == null) {
                return -1;
            }
            profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false);
            profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming);
        }

        try {
@@ -2425,7 +2433,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("  help");
            pw.println("      Print this help text.");
            pw.println("  start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]");
            pw.println("          [--sampling INTERVAL] [-R COUNT] [-S]");
            pw.println("          [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]");
            pw.println("          [--track-allocation] [--user <USER_ID> | current] <INTENT>");
            pw.println("      Start an Activity.  Options are:");
            pw.println("      -D: enable debugging");
@@ -2434,6 +2442,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("      --start-profiler <FILE>: start profiler and send results to <FILE>");
            pw.println("      --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
            pw.println("          between samples (use with --start-profiler)");
            pw.println("      --streaming: stream the profiling output to the specified file");
            pw.println("          (use with --start-profiler)");
            pw.println("      -P <FILE>: like above, but profiling stops when app goes idle");
            pw.println("      -R: repeat the activity launch <COUNT> times.  Prior to each repeat,");
            pw.println("          the top activity will be finished.");
@@ -2480,11 +2490,14 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("      stop: stop tracing IPC transactions and dump the results to file.");
            pw.println("      --dump-file <FILE>: Specify the file the trace should be dumped to.");
            pw.println("  profile [start|stop] [--user <USER_ID> current] [--sampling INTERVAL]");
            pw.println("          <PROCESS> <FILE>");
            pw.println("          [--streaming] <PROCESS> <FILE>");
            pw.println("      Start and stop profiler on a process.  The given <PROCESS> argument");
            pw.println("        may be either a process name or pid.  Options are:");
            pw.println("      --user <USER_ID> | current: When supplying a process name,");
            pw.println("          specify user of process to profile; uses current user if not specified.");
            pw.println("      --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
            pw.println("          between samples");
            pw.println("      --streaming: stream the profiling output to the specified file");
            pw.println("  dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>");
            pw.println("      Dump the heap of a process.  The given <PROCESS> argument may");
            pw.println("        be either a process name or pid.  Options are:");
Loading