Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e784f7a0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "WatchDog: dump hal pids when killing a process."

parents 82cff222 6b47c54a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -22,7 +22,8 @@ LOCAL_JAVA_LIBRARIES := \
    services.net \
    android.hardware.light@2.0-java \
    android.hardware.power@1.0-java \
    android.hardware.tv.cec@1.0-java
    android.hardware.tv.cec@1.0-java \
    android.hidl.manager@1.0-java

LOCAL_STATIC_JAVA_LIBRARIES := \
    tzdata_shared2 \
+52 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hidl.manager.V1_0.IServiceManager;
import android.os.Debug;
import android.os.Handler;
import android.os.IPowerManager;
@@ -42,6 +43,9 @@ import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

/** This class calls its monitor every minute. Killing this process if they don't return **/
public class Watchdog extends Thread {
@@ -75,6 +79,14 @@ public class Watchdog extends Thread {
        "com.android.bluetooth",  // Bluetooth service
    };

    public static final List<String> HAL_INTERFACES_OF_INTEREST = Arrays.asList(
        "android.hardware.audio@2.0::IDevicesFactory",
        "android.hardware.bluetooth@1.0::IBluetoothHci",
        "android.hardware.camera.provider@2.4::ICameraProvider",
        "android.hardware.vr@1.0::IVr",
        "android.hardware.media.omx@1.0::IOmx"
    );

    static Watchdog sWatchdog;

    /* This handler will be used to post message back onto the main thread */
@@ -344,6 +356,43 @@ public class Watchdog extends Thread {
        return builder.toString();
    }

    private ArrayList<Integer> getInterestingHalPids() {
        try {
            IServiceManager serviceManager = IServiceManager.getService();
            ArrayList<IServiceManager.InstanceDebugInfo> dump =
                    serviceManager.debugDump();
            HashSet<Integer> pids = new HashSet<>();
            for (IServiceManager.InstanceDebugInfo info : dump) {
                if (info.pid == IServiceManager.PidConstant.NO_PID) {
                    continue;
                }

                if (!HAL_INTERFACES_OF_INTEREST.contains(info.interfaceName)) {
                    continue;
                }

                pids.add(info.pid);
            }
            return new ArrayList<Integer>(pids);
        } catch (RemoteException e) {
            return new ArrayList<Integer>();
        }
    }

    private ArrayList<Integer> getInterestingNativePids() {
        ArrayList<Integer> pids = getInterestingHalPids();

        int[] nativePids = Process.getPidsForCommands(NATIVE_STACKS_OF_INTEREST);
        if (nativePids != null) {
            pids.ensureCapacity(pids.size() + nativePids.length);
            for (int i : nativePids) {
                pids.add(i);
            }
        }

        return pids;
    }

    @Override
    public void run() {
        boolean waitedHalf = false;
@@ -400,7 +449,7 @@ public class Watchdog extends Thread {
                        ArrayList<Integer> pids = new ArrayList<Integer>();
                        pids.add(Process.myPid());
                        ActivityManagerService.dumpStackTraces(true, pids, null, null,
                                NATIVE_STACKS_OF_INTEREST);
                            getInterestingNativePids());
                        waitedHalf = true;
                    }
                    continue;
@@ -417,13 +466,13 @@ public class Watchdog extends Thread {
            // Then kill this process so that the system will restart.
            EventLog.writeEvent(EventLogTags.WATCHDOG, subject);

            ArrayList<Integer> pids = new ArrayList<Integer>();
            ArrayList<Integer> pids = new ArrayList<>();
            pids.add(Process.myPid());
            if (mPhonePid > 0) pids.add(mPhonePid);
            // Pass !waitedHalf so that just in case we somehow wind up here without having
            // dumped the halfway stacks, we properly re-initialize the trace file.
            final File stack = ActivityManagerService.dumpStackTraces(
                    !waitedHalf, pids, null, null, NATIVE_STACKS_OF_INTEREST);
                    !waitedHalf, pids, null, null, getInterestingNativePids());

            // Give some extra time to make sure the stack traces get written.
            // The system's been hanging for a minute, another second or two won't hurt much.
+15 −16
Original line number Diff line number Diff line
@@ -5468,11 +5468,12 @@ public class ActivityManagerService extends IActivityManager.Stub
     *    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
     * @param nativeProcs optional list of native process names to dump stack crawls
     * @param nativePids optional list of native pids to dump stack crawls
     * @return file containing stack traces, or null if no dump file is configured
     */
    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
            ArrayList<Integer> nativePids) {
        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
        if (tracesPath == null || tracesPath.length() == 0) {
            return null;
@@ -5488,7 +5489,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            return null;
        }
        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
        return tracesFile;
    }
@@ -5530,7 +5531,8 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
            ArrayList<Integer> nativePids) {
        // Use a FileObserver to detect when traces finish writing.
        // The order of traces is considered important to maintain for legibility.
        DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
@@ -5551,10 +5553,8 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
            // Next collect the stacks of the native pids
            if (nativeProcs != null) {
                int[] pids = Process.getPidsForCommands(nativeProcs);
                if (pids != null) {
                    for (int pid : pids) {
            if (nativePids != null) {
                for (int pid : nativePids) {
                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
                    final long sime = SystemClock.elapsedRealtime();
@@ -5564,7 +5564,6 @@ public class ActivityManagerService extends IActivityManager.Stub
                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
                }
            }
            }
            // Lastly, measure CPU usage.
            if (processCpuTracker != null) {
+11 −1
Original line number Diff line number Diff line
@@ -870,12 +870,22 @@ class AppErrors {
            nativeProcs = NATIVE_STACKS_OF_INTEREST;
        }

        int[] pids = Process.getPidsForCommands(nativeProcs);
        ArrayList<Integer> nativePids = null;

        if (pids != null) {
            nativePids = new ArrayList<Integer>(pids.length);
            for (int i : pids) {
                nativePids.add(i);
            }
        }

        // For background ANRs, don't pass the ProcessCpuTracker to
        // avoid spending 1/2 second collecting stats to rank lastPids.
        File tracesFile = mService.dumpStackTraces(true, firstPids,
                                                   (isSilentANR) ? null : processCpuTracker,
                                                   (isSilentANR) ? null : lastPids,
                                                   nativeProcs);
                                                   nativePids);

        String cpuInfo = null;
        if (ActivityManagerService.MONITOR_CPU_USAGE) {