3. dumpsys工具入门

dumpsys 是 Android 系统中最核心的诊断工具之一,它运行在系统服务(System Server)进程中,能够查询所有已注册系统服务的内部状态。在 Binder 调试场景中,dumpsys 是获取服务端状态快照、验证服务调用链路是否正确的首选手段。本节将系统介绍 dumpsys 的基本用法、常用参数以及输出格式的解析方法。

调试前提:执行 dumpsys 需要 android.permission.DUMP 权限,或通过 adb shell 以 shell 用户身份运行。在 userdebug/eng 版本中权限限制较宽松,user 版本部分敏感服务可能拒绝 dump。

3.1 命令基本用法

dumpsys 命令的标准调用格式如下:

adb shell dumpsys [service_name] [options]

如果不指定服务名,dumpsys 会依次转储所有已注册服务的状态信息,输出量极大,通常不推荐在生产调试中直接使用。推荐始终指定目标服务名,以缩小输出范围、提高可读性。

命令形式 说明 典型场景
dumpsys 转储所有服务(不推荐) 仅用于快速验证 dump 机制是否正常
dumpsys activity 转储 ActivityManagerService 状态 分析 Activity 栈、进程、广播等
dumpsys window 转储 WindowManagerService 状态 查看窗口层级、焦点、输入法绑定
dumpsys package 转储 PackageManagerService 状态 查询已安装应用、权限、组件信息
dumpsys servicemanager 转储 ServiceManager 中的服务列表 验证服务是否注册、Binder 句柄是否有效
dumpsys media.camera 转储 CameraService 状态 调试相机 HAL 连接、会话状态
实战建议:在 Binder 调用链路分析中,最常配合使用的是 dumpsys servicemanager(查看服务注册情况)和 dumpsys <target_service>(查看具体服务的内部状态)。两者结合可以快速定位服务是否存活、Binder 代理是否有效。

3.2 常用参数详解

dumpsys 提供三个核心参数,用于查询服务列表、获取帮助信息以及向服务传递自定义选项。

3.2.1 -l:列出所有已注册服务

-l 参数仅输出服务名称列表,不包含任何状态数据。这是快速了解当前系统中有哪些服务可用的最佳方式。

adb shell dumpsys -l

# 输出示例(部分):
Currently running services:
  DockObserver
  accessibility
  account
  activity
  alarm
  android.security.keystore
  appops
  appwidget
  audio
  backup
  battery
  batteryproperties
  ...

输出按字母顺序排列,每个服务名对应一个 Binder 服务实体。在调试 Binder 调用时,如果目标服务未出现在此列表中,说明服务尚未注册或已崩溃,需要优先排查服务注册流程。

3.2.2 --help:查看服务支持的 dump 选项

每个服务可以自定义自己的 dump 输出格式和子选项。使用 --help 参数可以查看目标服务支持哪些附加参数:

adb shell dumpsys activity --help

# 输出示例(部分):
Activity manager dump options:
  [-a] [-c] [-p PACKAGES] [-h] [cmd] ...
  cmd may be one of:
    a[ctivities]: activity stack state
    b[roadcasts]: broadcast state
    i[ntents]: pending intent state
    p[rocesses]: process state
    o[om]: out of memory management
    ...

通过 --help 可以了解服务支持哪些细粒度过滤,例如只转储 Activity 栈、只转储进程信息等,避免被无关信息淹没。

3.2.3 服务名 + 自定义参数:精确控制输出内容

在指定服务名后,可以附加该服务支持的子参数,实现定向转储:

# 只转储 Activity 栈信息
adb shell dumpsys activity a

# 只转储广播接收器信息
adb shell dumpsys activity b

# 只转储指定包名的进程信息
adb shell dumpsys activity p com.example.app

这种精确控制对于 Binder 调用链路分析非常关键——当怀疑某个服务状态异常时,可以只转储与该服务相关的子模块,减少干扰。

注意:不同服务支持的子参数差异很大。部分服务(如 servicemanager)不支持 --help,此时直接运行 dumpsys <service> 即可看到完整输出。建议在调试新服务前先执行 dumpsys <service> --help 确认可用选项。

3.3 输出格式解析

dumpsys 的输出格式由各服务自行定义,没有统一标准。但大多数系统服务遵循一套约定俗成的结构,掌握这些规律可以大幅提升阅读效率。

3.3.1 通用结构模式

典型的 dumpsys 输出包含以下几个部分:

段落 内容 示例
头部标识 服务名称、版本、进程 ID ACTIVITY MANAGER (dumpsys)
全局状态 服务级别的计数器、配置、开关 mConfiguration: {1.0 460mcc...}
子模块列表 按功能划分的详细状态块 Stack #0: type=standard mode=fullscreen
Binder 代理信息 客户端连接数、Binder 引用计数 mConnections: size=3
性能/统计摘要 调用次数、耗时、异常计数 Total time: 1234ms

3.3.2 关键字段解读技巧

在 Binder 调试场景中,需要重点关注以下几类字段:

  • Binder 句柄与引用:形如 BinderProxy@0x1234abcd 或 IBinder: 0xdeadbeef,表示 Binder 代理对象的地址。如果出现大量 null 或 dead 标记,说明 Binder 连接已断裂。
  • 连接计数:形如 mConnections: size=5,表示当前有 5 个客户端通过 Binder 连接到该服务。数值异常(过大或为 0)可能暗示资源泄漏或服务未正确绑定。
  • 事务统计:形如 transactions: 1024 sent, 1024 received,用于判断 Binder 通信是否对称。发送与接收计数严重不匹配可能意味着事务丢失。
  • 线程池状态:形如 mThreadPool: active=4 idle=12,反映 Binder 线程池的负载情况。active 接近上限时可能出现 Binder 调用阻塞。

3.3.3 实战:解析 dumpsys servicemanager 输出

servicemanager 是 Binder 架构中的服务注册中心,其 dump 输出直接反映所有已注册服务的 Binder 句柄信息:

adb shell dumpsys servicemanager

# 输出示例:
Service Manager 0.1
  service 'activity' (0x1234) pid=1234 uid=1000
  service 'window' (0x5678) pid=1234 uid=1000
  service 'package' (0x9abc) pid=1234 uid=1000
  service 'media.camera' (0xdef0) pid=2345 uid=1013
  ...

每行包含:服务名、Binder 句柄(十六进制)、注册该服务的进程 PID、进程 UID。在 Binder 调用链路分析中,如果客户端无法找到某个服务,首先应检查此列表:服务是否存在?句柄是否有效?PID 是否与预期一致?

调试技巧:如果 dumpsys servicemanager 中目标服务存在,但客户端仍然无法调用,说明问题可能出在客户端获取 Binder 代理的方式上(如 ServiceConnection 未正确回调、Context 未正确获取)。此时应结合 dumpsys activity processes 查看客户端进程的 Binder 引用状态。

3.4 dumpsys 输出结构可视化

下图展示了 dumpsys 命令从输入到输出的完整流程,以及输出中各部分与 Binder 调试的对应关系:

dumpsys 命令流程与输出结构 dumpsys 命令流程与输出结构 adb shell dumpsys 指定服务名 + 参数 Binder 调用服务 服务端 dump() 回调 头部标识 服务名 / PID / 版本 全局状态 配置 / 计数器 / 开关 子模块列表 按功能划分的详细块 Binder 代理信息 句柄 / 引用 / 连接数 事务统计 发送 / 接收 / 耗时 线程池状态 活跃 / 空闲 / 上限 Binder 调试关注重点 Binder 句柄是否有效 → 连接计数是否正常 → 事务统计是否对称 → 线程池是否阻塞

3.5 常见问题与避坑指南

常见问题 1:dumpsys 输出为空或卡死
原因:目标服务内部 dump() 方法存在死锁或长时间 I/O 操作。
解决:使用 dumpsys -t 5 <service> 设置超时时间(单位秒),避免终端阻塞。如果超时后仍无输出,说明服务端 dump 逻辑存在严重问题,需检查服务端代码。
常见问题 2:dumpsys 输出中包含大量 "null" 或 "dead"
原因:服务持有的 Binder 代理对象已经失效,但未及时清理。
解决:在服务端 dump() 方法中增加 Binder 代理有效性检查,使用 linkToDeath 监听 Binder 死亡通知。如果客户端进程已死,服务端应主动释放相关代理。
进阶技巧:在分析 Binder 调用链路时,可以同时执行 dumpsys servicemanager 和 dumpsys <target_service>,将两份输出对比查看。前者确认服务注册状态,后者确认服务内部状态。如果服务已注册但内部状态异常(如连接数为 0),说明客户端与服务端之间的 Binder 连接尚未建立或已断开。

3.6 本章小结

dumpsys 是 Binder 调试中最基础也最强大的工具。通过本节学习,应掌握以下核心技能:

  • 使用 -l 快速列出所有服务,确认目标服务是否存活
  • 使用 --help 了解服务支持的子参数,实现精确转储
  • 解析输出中的 Binder 句柄、连接计数、事务统计等关键字段
  • 结合 servicemanager 和具体服务的 dump 输出,定位 Binder 调用链路中的故障点