From f6fee67b6ea83e1092d8386ebf478941946b9fce Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Thu, 28 Jan 2021 22:43:32 +0000 Subject: [PATCH] WatchDog: support dumping AIDL HALs Similar to how HIDL HALs are here, we don't know the commandline of the service, so we can dump them based on service name prefixes. Power stats and lights are added here, for parity w/ HIDL since these hvae been converted to AIDL. Fixes: 175322136 Test: after `adb shell am hang`, we can verify the light service is dumped, when it wasn't before: vsoc_x86_64:/data/anr # cat anr_2021-01-28-22-42-44-969 | grep light Cmd line: /vendor/bin/hw/android.hardware.lights-service.example Change-Id: I8c8b0cff0c102221875114015a5524c03cfb5b5c --- core/java/android/os/ServiceManager.java | 14 ++++++++ .../java/android/os/ServiceManagerNative.java | 4 +++ .../java/com/android/server/Watchdog.java | 32 +++++++++++++++---- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java index 71344f90de75a..f853e67f87d0c 100644 --- a/core/java/android/os/ServiceManager.java +++ b/core/java/android/os/ServiceManager.java @@ -287,6 +287,20 @@ public final class ServiceManager { } } + /** + * Get service debug info. + * @return an array of information for each service (like listServices, but with PIDs) + * @hide + */ + public static ServiceDebugInfo[] getServiceDebugInfo() { + try { + return getIServiceManager().getServiceDebugInfo(); + } catch (RemoteException e) { + Log.e(TAG, "error in getServiceDebugInfo", e); + return null; + } + } + /** * This is only intended to be called when the process is first being brought * up and bound by the activity manager. There is only one thread in the process diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java index b70b6b5d209e4..60acc57d0cfeb 100644 --- a/core/java/android/os/ServiceManagerNative.java +++ b/core/java/android/os/ServiceManagerNative.java @@ -103,6 +103,10 @@ class ServiceManagerProxy implements IServiceManager { throw new RemoteException(); } + public ServiceDebugInfo[] getServiceDebugInfo() throws RemoteException { + return mServiceManager.getServiceDebugInfo(); + } + /** * Same as mServiceManager but used by apps. * diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index ab24015a11749..c3f429430d646 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -31,6 +31,7 @@ import android.os.IPowerManager; import android.os.Looper; import android.os.Process; import android.os.RemoteException; +import android.os.ServiceDebugInfo; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; @@ -135,6 +136,11 @@ public class Watchdog extends Thread { "android.system.suspend@1.0::ISystemSuspend" ); + public static final String[] AIDL_INTERFACE_PREFIXES_OF_INTEREST = new String[] { + "android.hardware.light.ILights/", + "android.hardware.power.stats.IPowerStats/", + }; + private static Watchdog sWatchdog; /* This handler will be used to post message back onto the main thread */ @@ -515,12 +521,11 @@ public class Watchdog extends Thread { return builder.toString(); } - private static ArrayList getInterestingHalPids() { + private static void addInterestingHidlPids(HashSet pids) { try { IServiceManager serviceManager = IServiceManager.getService(); ArrayList dump = serviceManager.debugDump(); - HashSet pids = new HashSet<>(); for (IServiceManager.InstanceDebugInfo info : dump) { if (info.pid == IServiceManager.PidConstant.NO_PID) { continue; @@ -532,24 +537,37 @@ public class Watchdog extends Thread { pids.add(info.pid); } - return new ArrayList(pids); } catch (RemoteException e) { - return new ArrayList(); + Log.w(TAG, e); + } + } + + private static void addInterestingAidlPids(HashSet pids) { + ServiceDebugInfo[] infos = ServiceManager.getServiceDebugInfo(); + if (infos == null) return; + + for (ServiceDebugInfo info : infos) { + for (String prefix : AIDL_INTERFACE_PREFIXES_OF_INTEREST) { + if (info.name.startsWith(prefix)) { + pids.add(info.debugPid); + } + } } } static ArrayList getInterestingNativePids() { - ArrayList pids = getInterestingHalPids(); + HashSet pids = new HashSet<>(); + addInterestingAidlPids(pids); + addInterestingHidlPids(pids); 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; + return new ArrayList(pids); } @Override