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

Commit b9a5e4ad authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Add new debug feature to automatically create heap dumps.

Not yet working, unless you turn off SELinux enforcing.
We need to update SElinux to allow the system process
to give apps access to /data/system/heapdump/javaheap.bin.

Currently watching can only be enabled through the shell,
such as:

adb shell am set-watch-heap com.android.systemui 1024

The last number is the process pss size in bytes, so this is
asking us to warn if it goes about 1K which will be all the
time.

Change-Id: I2089e5db2927afca0bf01a363c6247ee5dcb26e8
parent eb803aef
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -117,6 +117,8 @@ public class Am extends BaseCommand {
                "       am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" +
                "       am set-debug-app [-w] [--persistent] <PACKAGE>\n" +
                "       am clear-debug-app\n" +
                "       am set-watch-heap <PROCESS> <MEM-LIMIT>\n" +
                "       am clear-watch-heap\n" +
                "       am monitor [--gdb <port>]\n" +
                "       am hang [--allow-restart]\n" +
                "       am restart\n" +
@@ -211,6 +213,11 @@ public class Am extends BaseCommand {
                "\n" +
                "am clear-debug-app: clear the previously set-debug-app.\n" +
                "\n" +
                "am set-watch-heap: start monitoring pss size of <PROCESS>, if it is at or\n" +
                "    above <HEAP-LIMIT> then a heap dump is collected for the user to report\n" +
                "\n" +
                "am clear-watch-heap: clear the previously set-watch-heap.\n" +
                "\n" +
                "am bug-report: request bug report generation; will launch UI\n" +
                "    when done to select where it should be delivered.\n" +
                "\n" +
@@ -342,6 +349,10 @@ public class Am extends BaseCommand {
            runSetDebugApp();
        } else if (op.equals("clear-debug-app")) {
            runClearDebugApp();
        } else if (op.equals("set-watch-heap")) {
            runSetWatchHeap();
        } else if (op.equals("clear-watch-heap")) {
            runClearWatchHeap();
        } else if (op.equals("bug-report")) {
            runBugReport();
        } else if (op.equals("monitor")) {
@@ -1172,6 +1183,17 @@ public class Am extends BaseCommand {
        mAm.setDebugApp(null, false, true);
    }

    private void runSetWatchHeap() throws Exception {
        String proc = nextArgRequired();
        String limit = nextArgRequired();
        mAm.setDumpHeapDebugLimit(proc, Long.parseLong(limit));
    }

    private void runClearWatchHeap() throws Exception {
        String proc = nextArgRequired();
        mAm.setDumpHeapDebugLimit(proc, -1);
    }

    private void runBugReport() throws Exception {
        mAm.requestBugReport();
        System.out.println("Your lovely bug report is being created; please be patient.");
+42 −0
Original line number Diff line number Diff line
@@ -2423,6 +2423,23 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            reply.writeNoException();
            return true;
        }

        case SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            String procName = data.readString();
            long maxMemSize = data.readLong();
            setDumpHeapDebugLimit(procName, maxMemSize);
            reply.writeNoException();
            return true;
        }

        case DUMP_HEAP_FINISHED_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            String path = data.readString();
            dumpHeapFinished(path);
            reply.writeNoException();
            return true;
        }
        }

        return super.onTransact(code, data, reply, flags);
@@ -5616,5 +5633,30 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
    }

    @Override
    public void setDumpHeapDebugLimit(String processName, long maxMemSize) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeString(processName);
        data.writeLong(maxMemSize);
        mRemote.transact(SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

    @Override
    public void dumpHeapFinished(String path) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeString(path);
        mRemote.transact(DUMP_HEAP_FINISHED_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

    private IBinder mRemote;
}
+4 −0
Original line number Diff line number Diff line
@@ -4247,6 +4247,10 @@ public final class ActivityThread {
        } else {
            Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
        }
        try {
            ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path);
        } catch (RemoteException e) {
        }
    }

    final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
+7 −2
Original line number Diff line number Diff line
@@ -482,6 +482,9 @@ public interface IActivityManager extends IInterface {
    public void systemBackupRestored() throws RemoteException;
    public void notifyCleartextNetwork(int uid, byte[] firstPacket) throws RemoteException;

    public void setDumpHeapDebugLimit(String processName, long maxMemSize) throws RemoteException;
    public void dumpHeapFinished(String path) throws RemoteException;

    /*
     * Private non-Binder interfaces
     */
@@ -813,4 +816,6 @@ public interface IActivityManager extends IInterface {
    int REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+284;
    int RESIZE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+285;
    int GET_LOCK_TASK_MODE_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+286;
    int SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+287;
    int DUMP_HEAP_FINISHED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+288;
}
+0 −1
Original line number Diff line number Diff line
@@ -415,7 +415,6 @@ public class Notification implements Parcelable
     * Bit to be bitwise-ored into the {@link #flags} field that should be
     * set if the notification should be canceled when it is clicked by the
     * user.

     */
    public static final int FLAG_AUTO_CANCEL        = 0x00000010;

Loading