use of com.android.internal.os.ProcessStats in project android_frameworks_base by ParanoidAndroid.
the class ActivityManagerService method dumpStackTraces.
private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
// Use a FileObserver to detect when traces finish writing.
// The order of traces is considered important to maintain for legibility.
FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
public synchronized void onEvent(int event, String path) {
notify();
}
};
try {
observer.startWatching();
// First collect all of the stacks of the most important pids.
if (firstPids != null) {
try {
int num = firstPids.size();
for (int i = 0; i < num; i++) {
synchronized (observer) {
Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
// Wait for write-close, give up after 200msec
observer.wait(200);
}
}
} catch (InterruptedException e) {
Log.wtf(TAG, e);
}
}
// Next measure CPU usage.
if (processStats != null) {
processStats.init();
System.gc();
processStats.update();
try {
synchronized (processStats) {
// measure over 1/2 second.
processStats.wait(500);
}
} catch (InterruptedException e) {
}
processStats.update();
// We'll take the stack crawls of just the top apps using CPU.
final int N = processStats.countWorkingStats();
int numProcs = 0;
for (int i = 0; i < N && numProcs < 5; i++) {
ProcessStats.Stats stats = processStats.getWorkingStats(i);
if (lastPids.indexOfKey(stats.pid) >= 0) {
numProcs++;
try {
synchronized (observer) {
Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
// Wait for write-close, give up after 200msec
observer.wait(200);
}
} catch (InterruptedException e) {
Log.wtf(TAG, e);
}
}
}
}
} finally {
observer.stopWatching();
}
if (nativeProcs != null) {
int[] pids = Process.getPidsForCommands(nativeProcs);
if (pids != null) {
for (int pid : pids) {
Debug.dumpNativeBacktraceToFile(pid, tracesPath);
}
}
}
}
use of com.android.internal.os.ProcessStats in project cornerstone by Onskreen.
the class ActivityManagerService method dumpStackTraces.
/**
* If a stack trace dump file is configured, dump process stack traces.
* @param clearTraces causes the dump file to be erased prior to the new
* traces being written, if true; when false, the new traces will be
* appended to any existing file content.
* @param firstPids of dalvik VM processes to dump stack traces for first
* @param lastPids of dalvik VM processes to dump stack traces for last
* @return file containing stack traces, or null if no dump file is configured
*/
public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, ProcessStats processStats, SparseArray<Boolean> lastPids) {
String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
if (tracesPath == null || tracesPath.length() == 0) {
return null;
}
File tracesFile = new File(tracesPath);
try {
File tracesDir = tracesFile.getParentFile();
if (!tracesDir.exists())
tracesFile.mkdirs();
// drwxrwxr-x
FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);
if (clearTraces && tracesFile.exists())
tracesFile.delete();
tracesFile.createNewFile();
// -rw-rw-rw-
FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1);
} catch (IOException e) {
Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
return null;
}
// Use a FileObserver to detect when traces finish writing.
// The order of traces is considered important to maintain for legibility.
FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
public synchronized void onEvent(int event, String path) {
notify();
}
};
try {
observer.startWatching();
// First collect all of the stacks of the most important pids.
try {
int num = firstPids.size();
for (int i = 0; i < num; i++) {
synchronized (observer) {
Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
// Wait for write-close, give up after 200msec
observer.wait(200);
}
}
} catch (InterruptedException e) {
Log.wtf(TAG, e);
}
// Next measure CPU usage.
if (processStats != null) {
processStats.init();
System.gc();
processStats.update();
try {
synchronized (processStats) {
// measure over 1/2 second.
processStats.wait(500);
}
} catch (InterruptedException e) {
}
processStats.update();
// We'll take the stack crawls of just the top apps using CPU.
final int N = processStats.countWorkingStats();
int numProcs = 0;
for (int i = 0; i < N && numProcs < 5; i++) {
ProcessStats.Stats stats = processStats.getWorkingStats(i);
if (lastPids.indexOfKey(stats.pid) >= 0) {
numProcs++;
try {
synchronized (observer) {
Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
// Wait for write-close, give up after 200msec
observer.wait(200);
}
} catch (InterruptedException e) {
Log.wtf(TAG, e);
}
}
}
}
return tracesFile;
} finally {
observer.stopWatching();
}
}
use of com.android.internal.os.ProcessStats in project cornerstone by Onskreen.
the class ActivityManagerService method dumpStackTraces.
private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
// Use a FileObserver to detect when traces finish writing.
// The order of traces is considered important to maintain for legibility.
FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
public synchronized void onEvent(int event, String path) {
notify();
}
};
try {
observer.startWatching();
// First collect all of the stacks of the most important pids.
if (firstPids != null) {
try {
int num = firstPids.size();
for (int i = 0; i < num; i++) {
synchronized (observer) {
Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
// Wait for write-close, give up after 200msec
observer.wait(200);
}
}
} catch (InterruptedException e) {
Log.wtf(TAG, e);
}
}
// Next measure CPU usage.
if (processStats != null) {
processStats.init();
System.gc();
processStats.update();
try {
synchronized (processStats) {
// measure over 1/2 second.
processStats.wait(500);
}
} catch (InterruptedException e) {
}
processStats.update();
// We'll take the stack crawls of just the top apps using CPU.
final int N = processStats.countWorkingStats();
int numProcs = 0;
for (int i = 0; i < N && numProcs < 5; i++) {
ProcessStats.Stats stats = processStats.getWorkingStats(i);
if (lastPids.indexOfKey(stats.pid) >= 0) {
numProcs++;
try {
synchronized (observer) {
Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
// Wait for write-close, give up after 200msec
observer.wait(200);
}
} catch (InterruptedException e) {
Log.wtf(TAG, e);
}
}
}
}
} finally {
observer.stopWatching();
}
if (nativeProcs != null) {
int[] pids = Process.getPidsForCommands(nativeProcs);
if (pids != null) {
for (int pid : pids) {
Debug.dumpNativeBacktraceToFile(pid, tracesPath);
}
}
}
}
use of com.android.internal.os.ProcessStats in project android_frameworks_base by ParanoidAndroid.
the class ActivityManagerService method appNotResponding.
final void appNotResponding(ProcessRecord app, ActivityRecord activity, ActivityRecord parent, boolean aboveSystem, final String annotation) {
ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
if (mController != null) {
try {
// 0 == continue, -1 = kill process immediately
int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
if (res < 0 && app.pid != MY_PID)
Process.killProcess(app.pid);
} catch (RemoteException e) {
mController = null;
Watchdog.getInstance().setActivityController(null);
}
}
long anrTime = SystemClock.uptimeMillis();
if (MONITOR_CPU_USAGE) {
updateCpuStatsNow();
}
synchronized (this) {
// PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
if (mShuttingDown) {
Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
return;
} else if (app.notResponding) {
Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
return;
} else if (app.crashing) {
Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
return;
}
// In case we come through here for the same app before completing
// this one, mark as anring now so we will bail out.
app.notResponding = true;
// Log the ANR to the event log.
EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, app.processName, app.info.flags, annotation);
// Dump thread traces as quickly as we can, starting with "interesting" processes.
firstPids.add(app.pid);
int parentPid = app.pid;
if (parent != null && parent.app != null && parent.app.pid > 0)
parentPid = parent.app.pid;
if (parentPid != app.pid)
firstPids.add(parentPid);
if (MY_PID != app.pid && MY_PID != parentPid)
firstPids.add(MY_PID);
for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
ProcessRecord r = mLruProcesses.get(i);
if (r != null && r.thread != null) {
int pid = r.pid;
if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
if (r.persistent) {
firstPids.add(pid);
} else {
lastPids.put(pid, Boolean.TRUE);
}
}
}
}
}
// Log the ANR to the main log.
StringBuilder info = new StringBuilder();
info.setLength(0);
info.append("ANR in ").append(app.processName);
if (activity != null && activity.shortComponentName != null) {
info.append(" (").append(activity.shortComponentName).append(")");
}
info.append("\n");
if (annotation != null) {
info.append("Reason: ").append(annotation).append("\n");
}
if (parent != null && parent != activity) {
info.append("Parent: ").append(parent.shortComponentName).append("\n");
}
final ProcessStats processStats = new ProcessStats(true);
File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
String cpuInfo = null;
if (MONITOR_CPU_USAGE) {
updateCpuStatsNow();
synchronized (mProcessStatsThread) {
cpuInfo = mProcessStats.printCurrentState(anrTime);
}
info.append(processStats.printCurrentLoad());
info.append(cpuInfo);
}
info.append(processStats.printCurrentState(anrTime));
Slog.e(TAG, info.toString());
if (tracesFile == null) {
// There is no trace file, so dump (only) the alleged culprit's threads to the log
Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
}
addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, cpuInfo, tracesFile, null);
if (mController != null) {
try {
// 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
int res = mController.appNotResponding(app.processName, app.pid, info.toString());
if (res != 0) {
if (res < 0 && app.pid != MY_PID)
Process.killProcess(app.pid);
return;
}
} catch (RemoteException e) {
mController = null;
Watchdog.getInstance().setActivityController(null);
}
}
// Unless configured otherwise, swallow ANRs in background processes & kill the process.
boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
synchronized (this) {
if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Slog.w(TAG, "Killing " + app + ": background ANR");
EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, app.processName, app.setAdj, "background ANR");
Process.killProcessQuiet(app.pid);
return;
}
// Set the app's notResponding state, and look up the errorReportReceiver
makeAppNotRespondingLocked(app, activity != null ? activity.shortComponentName : null, annotation != null ? "ANR " + annotation : "ANR", info.toString());
// Bring up the infamous App Not Responding dialog
Message msg = Message.obtain();
HashMap map = new HashMap();
msg.what = SHOW_NOT_RESPONDING_MSG;
msg.obj = map;
msg.arg1 = aboveSystem ? 1 : 0;
map.put("app", app);
if (activity != null) {
map.put("activity", activity);
}
mHandler.sendMessage(msg);
}
}
use of com.android.internal.os.ProcessStats in project cornerstone by Onskreen.
the class ActivityManagerService method appNotResponding.
final void appNotResponding(ProcessRecord app, ActivityRecord activity, ActivityRecord parent, final String annotation) {
ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
if (mController != null) {
try {
// 0 == continue, -1 = kill process immediately
int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
if (res < 0 && app.pid != MY_PID)
Process.killProcess(app.pid);
} catch (RemoteException e) {
mController = null;
}
}
long anrTime = SystemClock.uptimeMillis();
if (MONITOR_CPU_USAGE) {
updateCpuStatsNow();
}
synchronized (this) {
// PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
if (mShuttingDown) {
Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
return;
} else if (app.notResponding) {
Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
return;
} else if (app.crashing) {
Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
return;
}
// In case we come through here for the same app before completing
// this one, mark as anring now so we will bail out.
app.notResponding = true;
// Log the ANR to the event log.
EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, annotation);
// Dump thread traces as quickly as we can, starting with "interesting" processes.
firstPids.add(app.pid);
int parentPid = app.pid;
if (parent != null && parent.app != null && parent.app.pid > 0)
parentPid = parent.app.pid;
if (parentPid != app.pid)
firstPids.add(parentPid);
if (MY_PID != app.pid && MY_PID != parentPid)
firstPids.add(MY_PID);
for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
ProcessRecord r = mLruProcesses.get(i);
if (r != null && r.thread != null) {
int pid = r.pid;
if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
if (r.persistent) {
firstPids.add(pid);
} else {
lastPids.put(pid, Boolean.TRUE);
}
}
}
}
}
// Log the ANR to the main log.
StringBuilder info = new StringBuilder();
info.setLength(0);
info.append("ANR in ").append(app.processName);
if (activity != null && activity.shortComponentName != null) {
info.append(" (").append(activity.shortComponentName).append(")");
}
info.append("\n");
if (annotation != null) {
info.append("Reason: ").append(annotation).append("\n");
}
if (parent != null && parent != activity) {
info.append("Parent: ").append(parent.shortComponentName).append("\n");
}
final ProcessStats processStats = new ProcessStats(true);
File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
String cpuInfo = null;
if (MONITOR_CPU_USAGE) {
updateCpuStatsNow();
synchronized (mProcessStatsThread) {
cpuInfo = mProcessStats.printCurrentState(anrTime);
}
info.append(processStats.printCurrentLoad());
info.append(cpuInfo);
}
info.append(processStats.printCurrentState(anrTime));
Slog.e(TAG, info.toString());
if (tracesFile == null) {
// There is no trace file, so dump (only) the alleged culprit's threads to the log
Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
}
addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, cpuInfo, tracesFile, null);
if (mController != null) {
try {
// 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
int res = mController.appNotResponding(app.processName, app.pid, info.toString());
if (res != 0) {
if (res < 0 && app.pid != MY_PID)
Process.killProcess(app.pid);
return;
}
} catch (RemoteException e) {
mController = null;
}
}
// Unless configured otherwise, swallow ANRs in background processes & kill the process.
boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
synchronized (this) {
if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Slog.w(TAG, "Killing " + app + ": background ANR");
EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, app.processName, app.setAdj, "background ANR");
Process.killProcessQuiet(app.pid);
return;
}
// Set the app's notResponding state, and look up the errorReportReceiver
makeAppNotRespondingLocked(app, activity != null ? activity.shortComponentName : null, annotation != null ? "ANR " + annotation : "ANR", info.toString());
// Bring up the infamous App Not Responding dialog
Message msg = Message.obtain();
HashMap map = new HashMap();
msg.what = SHOW_NOT_RESPONDING_MSG;
msg.obj = map;
map.put("app", app);
if (activity != null) {
map.put("activity", activity);
}
mHandler.sendMessage(msg);
}
}
Aggregations