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:
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user