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

Commit bb44e42d 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

Merged-In: I8a5136a1c7330c8260b7c6c8da63f42a73aee275

Change-Id: I8a5136a1c7330c8260b7c6c8da63f42a73aee275
parent 95451d53
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ public class Am extends BaseCommand {
    private String mProfileFile;
    private int mSamplingInterval;
    private boolean mAutoStop;
    private boolean mStreaming;   // Streaming the profiling output to a file.
    private int mStackId;

    /**
@@ -127,7 +128,7 @@ public class Am extends BaseCommand {
        pw.println(
                "usage: am [subcommand] [options]\n" +
                "usage: am start [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" +
                "               [--sampling INTERVAL] [-R COUNT] [-S]\n" +
                "               [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]\n" +
                "               [--track-allocation] [--user <USER_ID> | current] <INTENT>\n" +
                "       am startservice [--user <USER_ID> | current] <INTENT>\n" +
                "       am stopservice [--user <USER_ID> | current] <INTENT>\n" +
@@ -138,7 +139,8 @@ public class Am extends BaseCommand {
                "       am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
                "               [--user <USER_ID> | current]\n" +
                "               [--no-window-animation] [--abi <ABI>] <COMPONENT>\n" +
                "       am profile start [--user <USER_ID> current] [--sampling INTERVAL] <PROCESS> <FILE>\n" +
                "       am profile start [--user <USER_ID> current] [--sampling INTERVAL]\n"+
                "               [--streaming] <PROCESS> <FILE>\n" +
                "       am profile stop [--user <USER_ID> current] [<PROCESS>]\n" +
                "       am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" +
                "       am set-debug-app [-w] [--persistent] <PACKAGE>\n" +
@@ -191,6 +193,8 @@ public class Am extends BaseCommand {
                "    --start-profiler <FILE>: start profiler and send results to <FILE>\n" +
                "    --sampling INTERVAL: use sample profiling with INTERVAL microseconds\n" +
                "        between samples (use with --start-profiler)\n" +
                "    --streaming: stream the profiling output to the specified file (use\n" +
                "        with --start-profiler)\n" +
                "    -P <FILE>: like above, but profiling stops when app goes idle\n" +
                "    -R: repeat the activity launch <COUNT> times.  Prior to each repeat,\n" +
                "        the top activity will be finished.\n" +
@@ -250,6 +254,9 @@ public class Am extends BaseCommand {
                "  may be either a process name or pid.  Options are:\n" +
                "    --user <USER_ID> | current: When supplying a process name,\n" +
                "        specify user of process to profile; uses current user if not specified.\n" +
                "    --sampling INTERVAL: use sample profiling with INTERVAL microseconds\n" +
                "        between samples\n" +
                "    --streaming: stream the profiling output to the specified file\n" +
                "\n" +
                "am dumpheap: dump the heap of a process.  The given <PROCESS> argument may\n" +
                "  be either a process name or pid.  Options are:\n" +
@@ -484,6 +491,7 @@ public class Am extends BaseCommand {
        mProfileFile = null;
        mSamplingInterval = 0;
        mAutoStop = false;
        mStreaming = false;
        mUserId = defUser;
        mStackId = INVALID_STACK_ID;

@@ -504,6 +512,8 @@ public class Am extends BaseCommand {
                    mAutoStop = false;
                } else if (opt.equals("--sampling")) {
                    mSamplingInterval = Integer.parseInt(nextArgRequired());
                } else if (opt.equals("--streaming")) {
                    mStreaming = true;
                } else if (opt.equals("-R")) {
                    mRepeat = Integer.parseInt(nextArgRequired());
                } else if (opt.equals("-S")) {
@@ -616,7 +626,8 @@ public class Am extends BaseCommand {
                    System.err.println("Consider using a file under /data/local/tmp/");
                    return;
                }
                profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop);
                profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
                                                mStreaming);
            }

            IActivityManager.WaitResult result = null;
@@ -974,6 +985,7 @@ public class Am extends BaseCommand {
        int userId = UserHandle.USER_CURRENT;
        int profileType = 0;
        mSamplingInterval = 0;
        mStreaming = false;

        String process = null;

@@ -987,6 +999,8 @@ public class Am extends BaseCommand {
                    userId = parseUserArg(nextArgRequired());
                } else if (opt.equals("--wall")) {
                    wall = true;
                } else if (opt.equals("--streaming")) {
                    mStreaming = true;
                } else if (opt.equals("--sampling")) {
                    mSamplingInterval = Integer.parseInt(nextArgRequired());
                } else {
@@ -1038,7 +1052,7 @@ public class Am extends BaseCommand {
                System.err.println("Consider using a file under /data/local/tmp/");
                return;
            }
            profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false);
            profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming);
        }

        try {
+5 −1
Original line number Diff line number Diff line
@@ -535,6 +535,7 @@ public final class ActivityThread {
        ParcelFileDescriptor profileFd;
        int samplingInterval;
        boolean autoStopProfiler;
        boolean streamingOutput;
        boolean profiling;
        boolean handlingProfiling;
        public void setProfiler(ProfilerInfo profilerInfo) {
@@ -560,6 +561,7 @@ public final class ActivityThread {
            profileFd = fd;
            samplingInterval = profilerInfo.samplingInterval;
            autoStopProfiler = profilerInfo.autoStopProfiler;
            streamingOutput = profilerInfo.streamingOutput;
        }
        public void startProfiling() {
            if (profileFd == null || profiling) {
@@ -568,7 +570,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);
@@ -5111,6 +5114,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
@@ -1391,6 +1391,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    ParcelFileDescriptor mProfileFd;
    int mSamplingInterval = 0;
    boolean mAutoStopProfiler = false;
    boolean mStreamingOutput = false;
    int mProfileType = 0;
    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
    String mMemWatchDumpProcName;
@@ -6587,12 +6588,14 @@ public final class ActivityManagerService extends ActivityManagerNative
            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)) {
@@ -6622,7 +6625,8 @@ public final class ActivityManagerService extends ActivityManagerNative
                profileFd = profileFd.dup();
            }
            ProfilerInfo profilerInfo = profileFile == null ? null
                : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
                : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
                                   profileStreamingOutput);
            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
@@ -12108,6 +12112,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            mProfileFd = profilerInfo.profileFd;
            mSamplingInterval = profilerInfo.samplingInterval;
            mAutoStopProfiler = profilerInfo.autoStopProfiler;
            mStreamingOutput = profilerInfo.streamingOutput;
            mProfileType = 0;
        }
    }
@@ -14992,7 +14997,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                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);
            }
        }
@@ -21511,6 +21516,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        mProfileFile = null;
        mProfileType = 0;
        mAutoStopProfiler = false;
        mStreamingOutput = false;
        mSamplingInterval = 0;
    }
Loading