diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 0386cff9edea1..5cffb780c69f0 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -4294,6 +4294,16 @@ public final class ActivityThread { } } + /** + * Public entrypoint to stop profiling. This is required to end profiling when the app crashes, + * so that profiler data won't be lost. + * + * @hide + */ + public void stopProfiling() { + mProfiler.stopProfiling(); + } + static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { if (managed) { try { diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index f81658e013442..3b8b7cb2ba2fe 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -86,6 +86,13 @@ public class RuntimeInit { Clog_e(TAG, message.toString(), e); } + // Try to end profiling. If a profiler is running at this point, and we kill the + // process (below), the in-memory buffer will be lost. So try to stop, which will + // flush the buffer. (This makes method trace profiling useful to debug crashes.) + if (ActivityThread.currentActivityThread() != null) { + ActivityThread.currentActivityThread().stopProfiling(); + } + // Bring up crash dialog, wait for it to be dismissed ActivityManagerNative.getDefault().handleApplicationCrash( mApplicationObject, new ApplicationErrorReport.CrashInfo(e));