本指南简要介绍了用于调试在 SDV 平台上运行的服务和应用的基本工具和技术。
连接到设备
用于连接到设备并与之交互的主要工具是 Android 调试桥 (adb)。验证 adb 是否位于系统的路径中。
使用网络连接
如果设备位于同一网络中,并且您知道其 IP 地址,则可以通过以太网进行连接。我们的系统仅使用网络连接来运行 adb:
# Connect to the device using its IP address and default port
adb connect <device_ip_address>:5555
连接到多台设备
如需从单个工作站管理多台设备,您可以通过不同的 IP 地址连接到这些设备。如果您在单个主机上运行多个虚拟机,则需要为每个设备分配不同的端口。这需要将每个 SDV 设备上的 adb 守护程序配置为监听唯一端口,例如,第一个设备监听 5555,第二个设备监听 5556。您还可以将主机配置为将这些端口转发到不同的客户机:
# Connect to the first device
adb connect <device_1_ip_address>:5555
# Connect to a second device
adb connect <device_2_ip_address>:5555
# Connect to a second VM on first device on different port
adb connect <device_1_ip_address>:5556
# List all connected devices to verify
adb devices
运行后续 adb 命令时,您可以使用 -s 标志及其完整地址 (ip:port) 来定位到特定设备:
# Run a shell command on the second VM on first device in the above example
adb -s <device_1_ip_address>:5556 shell
查看日志
当服务失败或行为异常时,请先检查日志。
使用 logcat(Android 日志)
logcat 会显示系统服务、代理和服务软件包中的日志:
# View all logs in real-time
adb logcat
# Filter logs by a specific tag (e.g., the name of your service)
adb logcat -s MyServiceTag
# Filter logs by priority (V: Verbose, D: Debug, I: Info, W: Warn, E: Error, F: Fatal)
# This shows only Error and Fatal messages for a specific tag
adb logcat MyServiceTag:E *:S
# Clear old logs before viewing new ones
adb logcat -c && adb logcat
# Show all logs and return
adb logcat -d
# Color logs by level
adb logcat -v color
# Show timestamps as time since boot
adb logcat -v monotonic
使用 dmesg(内核日志)
dmesg 会显示来自 Linux 内核的日志。这对于调试以下问题至关重要:
- 硬件和驱动程序问题
- 内核崩溃
- SELinux 拒绝 (
avc: denied) - 也会显示在 logcat 中
# View all kernel messages
adb shell dmesg
# Follow kernel messages in real-time
adb shell dmesg -w
访问 Cuttlefish 上的日志
在 Cuttlefish 虚拟设备上运行时,您可以直接从宿主机的文件系统访问日志文件。如果 adb 不可用,此功能尤其有用。当您启动 Cuttlefish 时,它会输出所有调试路径,您也可以使用 cvd fleet 查找所有正在运行的实例的调试路径。
- Logcat(Android 日志):
cuttlefish/instances/cvd-1/logs/logcat - 内核日志:
cuttlefish/instances/cvd-1/logs/kernel.log - Cuttlefish 启动器日志:
cuttlefish/instances/cvd-1/logs/launcher.log(有助于调试 Cuttlefish 环境本身)
您可以使用 cat、less 或 tail -f 等标准命令行工具实时查看这些文件。
与 shell 和文件系统交互
获取 shell 访问权限,以便直接在设备上运行命令、检查进程状态和浏览文件系统:
# Open an interactive shell on the device
adb shell
# From within the shell, you can check running processes
ps -A
# Or check the status of a specific service managed by init
getprop init.svc.<service_name>
执行文件系统操作
使用 adb push 和 adb pull 在主机和设备之间移动文件。使用此功能可部署测试脚本、更新配置或检索崩溃转储:
# Push a file from your computer to the device
adb push my_local_file.txt /data/local/tmp/
# Pull a file from the device to your computer
adb pull /data/tombstones/tombstone_00 .
调试应用 (C++/Rust)
您可以在线或离线调试应用。
使用 lldb 进行实时调试
请按照以下步骤使用 lldb 实时调试服务(如需从 Android Studio for Platform 附加调试程序,请参阅调试和测试以及调试平台代码):
使用 root 权限重启
adb(端口转发需要):adb root如果二进制文件具有调试符号,请从
out/target/product/[SDV_FLAVOR]/symbols/[PARTITION]/bin/[EXECUTABLE]推送未剥离的版本。例如,如需从system_ext和sdv_core_cf上传rpcagent,请运行以下命令:adb push out/target/product/sdv_core_cf/symbols/system_ext/bin/rpcagent /data/local/tmp使用
lldbclient.py便捷脚本连接到 LLDB 客户端:# Run and connect a binary on device, run on host: lldbclient.py -r /data/local/tmp/rpcagent # Connect to an existing process with PID 2759 lldbclient.py -p 2759此脚本会远程连接
lldb。如需查看所有可用标志,请运行lldbclient.py --help。
分析崩溃转储 (tombstone)
当服务崩溃时,系统会在 /data/tombstones/ 中生成一个墓碑文件。该文件包含堆栈轨迹、内存映射和其他重要信息。
拉取 tombstone 文件,然后使用符号感知工具(例如 lldb 或专用脚本)通过未剥离的二进制文件版本对其进行分析。
分析性能
SDV 支持多种性能测量工具。
检查 CPU 和内存用量
top:提供按 CPU 使用率排序的正在运行进程的实时视图。adb shell top -m 10 # Show top 10 processesprocrank:提供特定进程或整个系统的内存用量的详细细分。adb shell procrank
使用 dumpsys 获取服务状态
dumpsys 是一款功能强大的工具,可用于查询任何 Android 系统服务的内部状态。
# List all available services
adb shell dumpsys -l
# Dump the state of a specific service or agent
adb shell dumpsys <service_name>
使用 torq 进行性能分析
torq 是一种命令行工具,可简化 Android 上的性能分析和跟踪任务。它允许在系统性能分析期间运行 Simpleperf、Perfetto 和其他典型任务。
使用 Perfetto 进行跟踪
Perfetto 是 Android 上用于系统级跟踪的标准工具。Perfetto 可让您记录系统事件、应用级跟踪点和性能计数器,并在时间轴上直观呈现。
关键步骤:
- 在 C++ 或 Rust 代码中添加跟踪点:
- C++:将 Perfetto SDK 与
TRACE_EVENT宏搭配使用。 - Rust:使用
tracingcrate,它会发出与 Perfetto 兼容的 ATrace 事件。
- C++:将 Perfetto SDK 与
- 创建一个 textproto 配置文件,以指定数据源(例如
ftrace、track_event)、类别和标记。 - 将
record_android_trace脚本 (external/perfetto/tools/record_android_trace) 与配置文件搭配使用,以从设备中捕获跟踪记录。 - 在 Perfetto Web 界面中打开生成的跟踪文件,以分析系统行为、识别瓶颈并了解服务交互。
如需详细了解插桩、配置和收集,请参阅使用跟踪功能深入了解系统性能。
使用 Simpleperf 进行性能分析
Simpleperf 是一款功能多样的命令行工具,用于在 Android 上进行性能分析,类似于 Linux perf。
常见使用情形:
- CPU 性能分析:识别消耗最多 CPU 时间的函数。
- 非 CPU 分析:分析线程休眠或阻塞的原因。
- 硬件计数器:访问硬件性能计数器。
示例命令:
# Go to simpleperf scripts
cd system/extras/simpleperf/scripts
# Profile system for 20 seconds and record call graph
./app_profiler.py --system_wide -r "--call-graph fp --duration 20"
# Record a profile for a specific process (PID 1)
./app_profiler.py --pid 1 -r "--call-graph fp --duration 5"
# Pull the profile data
adb pull /data/local/tmp/perf.data .
# Generate a report with symbol resolution
./report_html.py --add_source_code --source_dirs $ANDROID_BUILD_TOP --add_disassembly -o report.html
Simpleperf 还提供了许多其他事件和选项。如需查看完整文档,请参阅 Simpleperf 指南。
SELinux 拒绝
问题:您的服务无法启动、无法访问文件或无法使用某项功能,并且您在 dmesg 或 logcat 中看到 avc: denied 消息。
[ 123.456] avc: denied { read } for pid=789 comm="my_service" name="some_file" dev="sda1" ino=123 scontext=u:r:my_service_t:s0 tcontext=u:object_r:some_file_t:s0 tclass=file permissive=0
快速调试(仅限开发阶段)
您可以暂时停用 SELinux 强制执行,看看问题是否得到解决。这证实了问题是由于缺少 SELinux 政策规则导致的。
# Disabling SELinux requires root permission
adb root
# Set SELinux to permissive mode
adb shell setenforce 0
# Check the current mode (should return "Permissive")
adb shell getenforce
修复:针对拒绝消息,使用 Android 源代码树中的 audit2allow 工具。这会生成正确的 .te 政策规则,以添加到设备的 SELinux 配置中。