Search in sources :

Example 1 with ProcessStats

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);
            }
        }
    }
}
Also used : ProcessStats(com.android.internal.os.ProcessStats) FileObserver(android.os.FileObserver)

Example 2 with ProcessStats

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();
    }
}
Also used : ProcessStats(com.android.internal.os.ProcessStats) IOException(java.io.IOException) File(java.io.File) FileObserver(android.os.FileObserver)

Example 3 with ProcessStats

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);
            }
        }
    }
}
Also used : ProcessStats(com.android.internal.os.ProcessStats) FileObserver(android.os.FileObserver)

Example 4 with ProcessStats

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);
    }
}
Also used : ProcessStats(com.android.internal.os.ProcessStats) Message(android.os.Message) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) SparseArray(android.util.SparseArray) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RemoteException(android.os.RemoteException) File(java.io.File)

Example 5 with ProcessStats

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);
    }
}
Also used : ProcessStats(com.android.internal.os.ProcessStats) Message(android.os.Message) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) SparseArray(android.util.SparseArray) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RemoteException(android.os.RemoteException) File(java.io.File)

Aggregations

ProcessStats (com.android.internal.os.ProcessStats)5 FileObserver (android.os.FileObserver)3 File (java.io.File)3 Message (android.os.Message)2 RemoteException (android.os.RemoteException)2 SparseArray (android.util.SparseArray)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 IOException (java.io.IOException)1