* commit '5b88a2fd7b77880f6e09ae4a1de509bebe28bc3a': Debugging help for issue #8734824: WATCHDOG KILLING SYSTEM PROCESS
This commit is contained in:
@ -1093,6 +1093,18 @@ public class Am extends BaseCommand {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int systemNotResponding(String message)
|
||||
throws RemoteException {
|
||||
synchronized (this) {
|
||||
System.out.println("** ERROR: PROCESS NOT RESPONDING");
|
||||
System.out.println("message: " + message);
|
||||
System.out.println("#");
|
||||
System.out.println("Allowing system to die.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void killGdbLocked() {
|
||||
mGotGdbPrint = false;
|
||||
if (mGdbProcess != null) {
|
||||
|
@ -58,4 +58,11 @@ interface IActivityController
|
||||
* immediately.
|
||||
*/
|
||||
int appNotResponding(String processName, int pid, String processStats);
|
||||
|
||||
/**
|
||||
* The system process watchdog has detected that the system seems to be
|
||||
* hung. Return 1 to continue waiting, or -1 to let it continue with its
|
||||
* normal kill.
|
||||
*/
|
||||
int systemNotResponding(String msg);
|
||||
}
|
||||
|
@ -49,6 +49,11 @@ public class Binder implements IBinder {
|
||||
private static final boolean FIND_POTENTIAL_LEAKS = false;
|
||||
private static final String TAG = "Binder";
|
||||
|
||||
/**
|
||||
* Control whether dump() calls are allowed.
|
||||
*/
|
||||
private static String sDumpDisabled = null;
|
||||
|
||||
/* mObject is used by native code, do not remove or rename */
|
||||
private int mObject;
|
||||
private IInterface mOwner;
|
||||
@ -224,7 +229,23 @@ public class Binder implements IBinder {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Control disabling of dump calls in this process. This is used by the system
|
||||
* process watchdog to disable incoming dump calls while it has detecting the system
|
||||
* is hung and is reporting that back to the activity controller. This is to
|
||||
* prevent the controller from getting hung up on bug reports at this point.
|
||||
* @hide
|
||||
*
|
||||
* @param msg The message to show instead of the dump; if null, dumps are
|
||||
* re-enabled.
|
||||
*/
|
||||
public static void setDumpDisabled(String msg) {
|
||||
synchronized (Binder.class) {
|
||||
sDumpDisabled = msg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation is a stub that returns false. You will want
|
||||
* to override this to do the appropriate unmarshalling of transactions.
|
||||
@ -269,7 +290,15 @@ public class Binder implements IBinder {
|
||||
FileOutputStream fout = new FileOutputStream(fd);
|
||||
PrintWriter pw = new PrintWriter(fout);
|
||||
try {
|
||||
dump(fd, pw, args);
|
||||
final String disabled;
|
||||
synchronized (Binder.class) {
|
||||
disabled = sDumpDisabled;
|
||||
}
|
||||
if (disabled == null) {
|
||||
dump(fd, pw, args);
|
||||
} else {
|
||||
pw.println(sDumpDisabled);
|
||||
}
|
||||
} finally {
|
||||
pw.flush();
|
||||
}
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.server;
|
||||
|
||||
import android.app.IActivityController;
|
||||
import android.os.Binder;
|
||||
import android.os.RemoteException;
|
||||
import com.android.server.am.ActivityManagerService;
|
||||
import com.android.server.power.PowerManagerService;
|
||||
|
||||
@ -91,6 +94,7 @@ public class Watchdog extends Thread {
|
||||
Monitor mCurrentMonitor;
|
||||
|
||||
int mPhonePid;
|
||||
IActivityController mController;
|
||||
|
||||
final Calendar mCalendar = Calendar.getInstance();
|
||||
int mMinScreenOff = MEMCHECK_DEFAULT_MIN_SCREEN_OFF;
|
||||
@ -223,6 +227,12 @@ public class Watchdog extends Thread {
|
||||
}
|
||||
}
|
||||
|
||||
public void setActivityController(IActivityController controller) {
|
||||
synchronized (this) {
|
||||
mController = controller;
|
||||
}
|
||||
}
|
||||
|
||||
public void addMonitor(Monitor monitor) {
|
||||
synchronized (this) {
|
||||
if (isAlive()) {
|
||||
@ -476,6 +486,25 @@ public class Watchdog extends Thread {
|
||||
dropboxThread.join(2000); // wait up to 2 seconds for it to return.
|
||||
} catch (InterruptedException ignored) {}
|
||||
|
||||
IActivityController controller;
|
||||
synchronized (this) {
|
||||
controller = mController;
|
||||
}
|
||||
if (controller != null) {
|
||||
Slog.i(TAG, "Reporting stuck state to activity controller");
|
||||
try {
|
||||
Binder.setDumpDisabled("Service dumps disabled due to hung system process.");
|
||||
// 1 = keep waiting, -1 = kill system
|
||||
int res = controller.systemNotResponding(name);
|
||||
if (res >= 0) {
|
||||
Slog.i(TAG, "Activity controller requested to coninue to wait");
|
||||
waitedHalf = false;
|
||||
continue;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Only kill the process if the debugger is not attached.
|
||||
if (!Debug.isDebuggerConnected()) {
|
||||
Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
|
||||
|
@ -2822,6 +2822,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
resumeOK = mController.activityResuming(next.packageName);
|
||||
} catch (RemoteException e) {
|
||||
mController = null;
|
||||
Watchdog.getInstance().setActivityController(null);
|
||||
}
|
||||
|
||||
if (!resumeOK) {
|
||||
@ -3334,6 +3335,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
|
||||
} catch (RemoteException e) {
|
||||
mController = null;
|
||||
Watchdog.getInstance().setActivityController(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3437,6 +3439,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
mController = null;
|
||||
Watchdog.getInstance().setActivityController(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7441,6 +7444,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
"setActivityController()");
|
||||
synchronized (this) {
|
||||
mController = controller;
|
||||
Watchdog.getInstance().setActivityController(controller);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8832,6 +8836,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
mController = null;
|
||||
Watchdog.getInstance().setActivityController(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12765,6 +12770,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
resumeOK = mController.activityResuming(next.packageName);
|
||||
} catch (RemoteException e) {
|
||||
mController = null;
|
||||
Watchdog.getInstance().setActivityController(null);
|
||||
}
|
||||
|
||||
if (!resumeOK) {
|
||||
|
Reference in New Issue
Block a user