OSDN Git Service

WatchDog: dump hal pids when killing a process.
authorSteven Moreland <smoreland@google.com>
Tue, 21 Mar 2017 19:52:16 +0000 (12:52 -0700)
committerSteven Moreland <smoreland@google.com>
Mon, 27 Mar 2017 15:06:54 +0000 (08:06 -0700)
Test: `adb shell am hang --allow-restart` -> Watchdog dumps
  hal traces (eventually)
Bug: 36414311
Change-Id: I5143cedf3e5ab4695d2507a29993e748f6de17d5

services/core/Android.mk
services/core/java/com/android/server/Watchdog.java
services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/am/AppErrors.java

index e35a171..099f557 100644 (file)
@@ -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 \
index ce4ca02..80f89fc 100644 (file)
@@ -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.
index 4fc60f9..ef2cc81 100644 (file)
@@ -5460,11 +5460,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;
@@ -5480,7 +5481,7 @@ public class ActivityManagerService extends IActivityManager.Stub
             return null;
         }
 
-        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
+        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
         return tracesFile;
     }
 
@@ -5522,7 +5523,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);
@@ -5543,18 +5545,15 @@ 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 (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
-                        final long sime = SystemClock.elapsedRealtime();
-
-                        Debug.dumpNativeBacktraceToFileTimeout(
-                                pid, tracesPath, DumpStackFileObserver.TRACE_DUMP_TIMEOUT_SECONDS);
-                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
-                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
-                    }
+            if (nativePids != null) {
+                for (int pid : nativePids) {
+                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
+                    final long sime = SystemClock.elapsedRealtime();
+
+                    Debug.dumpNativeBacktraceToFileTimeout(
+                            pid, tracesPath, DumpStackFileObserver.TRACE_DUMP_TIMEOUT_SECONDS);
+                    if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
+                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
                 }
             }
 
index f927cce..7b1af38 100644 (file)
@@ -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) {