If a crash dialog can't be shown, just kill the process.

scheduleCrash() calls into the app process to ask it to nicely show
the crash dialog. If that call fails, rather than just silently
stopping, kill the process right away. It might be out of control.

This also adds an additional check for killedByAm to the flow there
so if the activity manager already has killed it, the dialog won't
be shown.

Bug: 28196243
Change-Id: I979f01074e5890640e7b06e29eeb0d6c38803569
This commit is contained in:
Joe Onorato
2016-04-20 15:37:49 -07:00
parent 59c9a93fc2
commit 5719028766
2 changed files with 26 additions and 13 deletions

View File

@@ -293,19 +293,7 @@ class AppErrors {
return;
}
if (proc.thread != null) {
if (proc.pid == Process.myPid()) {
Log.w(TAG, "crashApplication: trying to crash self!");
return;
}
long ident = Binder.clearCallingIdentity();
try {
proc.thread.scheduleCrash(message);
} catch (RemoteException e) {
} finally {
Binder.restoreCallingIdentity(ident);
}
}
proc.scheduleCrash(message);
}
/**

View File

@@ -37,9 +37,11 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
@@ -552,6 +554,29 @@ final class ProcessRecord {
return adj;
}
void scheduleCrash(String message) {
// Checking killedbyAm should keep it from showing the crash dialog if the process
// was already dead for a good / normal reason.
if (!killedByAm) {
if (thread != null) {
if (pid == Process.myPid()) {
Slog.w(TAG, "scheduleCrash: trying to crash system process!");
return;
}
long ident = Binder.clearCallingIdentity();
try {
thread.scheduleCrash(message);
} catch (RemoteException e) {
// If it's already dead our work is done. If it's wedged just kill it.
// We won't get the crash dialog or the error reporting.
kill("scheduleCrash for '" + message + "' failed", true);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}
}
void kill(String reason, boolean noisy) {
if (!killedByAm) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill");