From 5719028766f51512beffa623db7ee682851570a0 Mon Sep 17 00:00:00 2001 From: Joe Onorato Date: Wed, 20 Apr 2016 15:37:49 -0700 Subject: [PATCH] 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 --- .../java/com/android/server/am/AppErrors.java | 14 +---------- .../com/android/server/am/ProcessRecord.java | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 13 deletions(-) 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");