diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 68bd2fd3ce3e8..e9ed34b18baa4 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -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); } /** diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 93d40604dbda4..059acbd4190f0 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -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");