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

Commit 8aa8fe12 authored by Christopher Tate's avatar Christopher Tate Committed by Chris Tate
Browse files

Add an 'am crash' shell command

Induce a normal VM crash via adb, because it's quite different from the
effects of 'am kill'.

Test: induced crashes via adb shell using both pid & pkg

Change-Id: I79654afa7c4a70364cfd7d3af3e80a7b0e59b882
parent 4a65687b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -264,7 +264,7 @@ interface IActivityManager {
    boolean isImmersive(in IBinder token);
    void setImmersive(in IBinder token, boolean immersive);
    boolean isTopActivityImmersive();
    void crashApplication(int uid, int initialPid, in String packageName, in String message);
    void crashApplication(int uid, int initialPid, in String packageName, int userId, in String message);
    String getProviderMimeType(in Uri uri, int userId);
    IBinder newUriPermissionOwner(in String name);
    void grantUriPermissionFromOwner(in IBinder owner, int fromUid, in String targetPkg,
+2 −2
Original line number Diff line number Diff line
@@ -4936,7 +4936,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    @Override
    public void crashApplication(int uid, int initialPid, String packageName,
    public void crashApplication(int uid, int initialPid, String packageName, int userId,
            String message) {
        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
                != PackageManager.PERMISSION_GRANTED) {
@@ -4949,7 +4949,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
        synchronized(this) {
            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
        }
    }
+30 −0
Original line number Diff line number Diff line
@@ -167,6 +167,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    return runBugReport(pw);
                case "force-stop":
                    return runForceStop(pw);
                case "crash":
                    return runCrash(pw);
                case "kill":
                    return runKill(pw);
                case "kill-all":
@@ -851,6 +853,32 @@ final class ActivityManagerShellCommand extends ShellCommand {
        return 0;
    }

    int runCrash(PrintWriter pw) throws RemoteException {
        int userId = UserHandle.USER_ALL;

        String opt;
        while ((opt=getNextOption()) != null) {
            if (opt.equals("--user")) {
                userId = UserHandle.parseUserArg(getNextArgRequired());
            } else {
                getErrPrintWriter().println("Error: Unknown option: " + opt);
                return -1;
            }
        }

        int pid = -1;
        String packageName = null;
        final String arg = getNextArgRequired();
        // The argument is either a pid or a package name
        try {
            pid = Integer.parseInt(arg);
        } catch (NumberFormatException e) {
            packageName = arg;
        }
        mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash");
        return 0;
    }

    int runKill(PrintWriter pw) throws RemoteException {
        int userId = UserHandle.USER_ALL;

@@ -2480,6 +2508,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("     --telephony: will dump only telephony sections.");
            pw.println("  force-stop [--user <USER_ID> | all | current] <PACKAGE>");
            pw.println("      Completely stop the given application package.");
            pw.println("  crash [--user <USER_ID>] <PACKAGE|PID>");
            pw.println("      Induce a VM crash in the specified package or process");
            pw.println("  kill [--user <USER_ID> | all | current] <PACKAGE>");
            pw.println("      Kill all processes associated with the given application.");
            pw.println("  kill-all");
+15 −4
Original line number Diff line number Diff line
@@ -259,7 +259,16 @@ class AppErrors {
        }
    }

    void scheduleAppCrashLocked(int uid, int initialPid, String packageName,
    /**
     * Induce a crash in the given app.
     *
     * @param uid if nonnegative, the required matching uid of the target to crash
     * @param initialPid fast-path match for the target to crash
     * @param packageName fallback match if the stated pid is not found or doesn't match uid
     * @param userId If nonnegative, required to identify a match by package name
     * @param message
     */
    void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
            String message) {
        ProcessRecord proc = null;

@@ -270,14 +279,15 @@ class AppErrors {
        synchronized (mService.mPidsSelfLocked) {
            for (int i=0; i<mService.mPidsSelfLocked.size(); i++) {
                ProcessRecord p = mService.mPidsSelfLocked.valueAt(i);
                if (p.uid != uid) {
                if (uid >= 0 && p.uid != uid) {
                    continue;
                }
                if (p.pid == initialPid) {
                    proc = p;
                    break;
                }
                if (p.pkgList.containsKey(packageName)) {
                if (p.pkgList.containsKey(packageName)
                        && (userId < 0 || p.userId == userId)) {
                    proc = p;
                }
            }
@@ -286,7 +296,8 @@ class AppErrors {
        if (proc == null) {
            Slog.w(TAG, "crashApplication: nothing for uid=" + uid
                    + " initialPid=" + initialPid
                    + " packageName=" + packageName);
                    + " packageName=" + packageName
                    + " userId=" + userId);
            return;
        }

+1 −1
Original line number Diff line number Diff line
@@ -534,7 +534,7 @@ final class ServiceRecord extends Binder {
                        // get to be foreground.
                        ams.setServiceForeground(name, ServiceRecord.this,
                                0, null, 0);
                        ams.crashApplication(appUid, appPid, localPackageName,
                        ams.crashApplication(appUid, appPid, localPackageName, -1,
                                "Bad notification for startForeground: " + e);
                    }
                }
Loading