Merge changes I036fbc5f,I979f0107 into nyc-dev

* changes:
  If we can't call into an app process to deliver an intent, crash the process.
  If a crash dialog can't be shown, just kill the process.
This commit is contained in:
Joe Onorato
2016-04-21 22:36:21 +00:00
committed by Android (Google) Code Review
3 changed files with 46 additions and 16 deletions

View File

@@ -293,19 +293,7 @@ class AppErrors {
return; return;
} }
if (proc.thread != null) { proc.scheduleCrash(message);
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);
}
}
} }
/** /**

View File

@@ -38,6 +38,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.DeadObjectException;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
@@ -446,7 +447,7 @@ public final class BroadcastQueue {
} }
} }
private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, private void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras, Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser) throws RemoteException { boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls. // Send the intent to the receiver asynchronously using one-way binder calls.
@@ -454,8 +455,23 @@ public final class BroadcastQueue {
if (app.thread != null) { if (app.thread != null) {
// If we have an app thread, do the call through that so it is // If we have an app thread, do the call through that so it is
// correctly ordered with other one-way calls. // correctly ordered with other one-way calls.
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, try {
data, extras, ordered, sticky, sendingUser, app.repProcState); app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.repProcState);
// TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
// DeadObjectException when the process isn't actually dead.
//} catch (DeadObjectException ex) {
// Failed to call into the process. It's dying so just let it die and move on.
// throw ex;
} catch (RemoteException ex) {
// Failed to call into the process. It's either dying or wedged. Kill it gently.
synchronized (mService) {
Slog.w(TAG, "Can't deliver broadcast to " + app.processName
+ " (pid " + app.pid + "). Crashing it.");
app.scheduleCrash("can't deliver broadcast");
}
throw ex;
}
} else { } else {
// Application has died. Receiver doesn't exist. // Application has died. Receiver doesn't exist.
throw new RemoteException("app.thread must not be null"); throw new RemoteException("app.thread must not be null");
@@ -853,6 +869,7 @@ public final class BroadcastQueue {
Slog.w(TAG, "Failure [" Slog.w(TAG, "Failure ["
+ mQueueName + "] sending broadcast result of " + mQueueName + "] sending broadcast result of "
+ r.intent, e); + r.intent, e);
} }
} }

View File

@@ -37,9 +37,11 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo; import android.content.res.CompatibilityInfo;
import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.Process; import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.Trace; import android.os.Trace;
import android.os.UserHandle; import android.os.UserHandle;
@@ -552,6 +554,29 @@ final class ProcessRecord {
return adj; 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) { void kill(String reason, boolean noisy) {
if (!killedByAm) { if (!killedByAm) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill"); Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill");