2. 稳定性测试基础:定义、环境与工具链
稳定性是 Camera HAL 投入商用的最低门槛。本章从三个维度建立稳定性测试的基线:稳定性定义(明确衡量标准)、测试环境搭建(保障可复现性)、常用工具链(定位问题的“眼睛”)。
核心观点:稳定性测试不是“跑一跑不出错就行”,而是要在压力下验证系统无 Crash、无 ANR、无内存泄漏,并通过标准化的环境与工具链将问题快速定位到 HAL 层代码。
2.1 稳定性定义:三大核心指标
在 Camera HAL 领域,稳定性不是模糊的“不出问题”,而是可量化、可验证的工程指标。以下三个维度构成稳定性测试的基石:
| 指标 | 定义 | HAL 层典型表现 | 检测手段 |
|---|---|---|---|
| 无 Crash | 进程(如 cameraserver)在压力测试期间不异常退出 | HAL 函数返回错误、空指针解引用、buffer 越界 | logcat 搜索 fatal/signal/abort;tombstone 分析 |
| 无 ANR | 应用主线程或 Binder 调用在 5s/20s 内未响应 | HAL 的 processCaptureRequest 阻塞超过 1s;flush 卡死 | logcat 搜索 ANR in;traces.txt 查看堆栈 |
| 无内存泄漏 | 进程 RSS 在长时间压力下不持续增长 | native 层 new 后未 delete;gralloc buffer 未释放 | dumpsys meminfo;/proc/pid/status 监控 VmRSS |
经验法则:在 8 小时连续压力测试中,cameraserver 的 RSS 增长不应超过 5MB。若发现“锯齿状”内存曲线(每次拍照后内存上升但不回落),基本可判定存在 native 内存泄漏。
2.2 测试环境搭建:从 adb 到 root 权限
稳定性测试对环境的要求比功能测试更严格:需要可复现、可监控、可干预。以下是标准环境搭建步骤:
2.2.1 基础连接与设备准备
# 1. 确认设备连接
adb devices -l
# 输出示例:ABCDEF device product:xxx model:XXX
# 2. 获取 root 权限(稳定性测试必备)
adb root
adb remount # 重新挂载 /system 为可读写
# 3. 关闭 SELinux(避免权限干扰)
adb shell setenforce 0
adb shell getenforce # 确认输出:Permissive
# 4. 设置性能模式(避免降频影响)
adb shell echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
2.2.2 关键环境配置清单
| 配置项 | 命令/操作 | 说明 |
|---|---|---|
| 关闭屏幕超时 | adb shell settings put system screen_off_timeout 1800000 |
防止测试过程中屏幕关闭导致相机服务休眠 |
| 关闭自动更新 | adb shell pm disable com.android.systemui(谨慎) |
避免系统服务重启干扰测试 |
| 设置 log 缓冲区 | adb logcat -G 16M |
增大 log 缓冲区,防止压力测试时 log 被冲刷 |
| 关闭看门狗 | adb shell echo V > /proc/sys/kernel/printk |
减少内核 log 干扰,但需注意风险 |
| 固定 CPU 频率 | adb shell echo 1 > /sys/devices/system/cpu/cpu0/online |
确保测试结果不受 DVFS 影响 |
注意:root 权限和关闭 SELinux 在生产环境中不可用,但稳定性测试阶段必须开启,否则无法捕获底层 HAL 的完整错误信息。测试完成后务必恢复:
adb shell setenforce 1。
2.3 常用工具链:logcat / dmesg / tombstone
稳定性问题的定位高度依赖工具链。以下三个工具是 Camera HAL 稳定性分析的“三驾马车”:
2.3.1 logcat:用户态问题第一现场
logcat 是 Android 用户态日志的核心出口,Camera HAL 的 ALOGE/ALOGW 均输出至此。稳定性测试中,以下过滤命令必须掌握:
# 1. 实时过滤 Camera 相关日志(推荐)
adb logcat -v threadtime | grep -E "CameraService|CameraHAL|camera|HAL"
# 2. 捕获 ANR 日志(带时间戳)
adb logcat -b events -v threadtime | grep -E "am_anr|am_crash"
# 3. 捕获 native crash 日志
adb logcat -v threadtime -b crash
# 4. 保存完整日志到本地(压力测试后分析)
adb logcat -d -v threadtime > /tmp/camera_stability_$(date +%Y%m%d_%H%M%S).log
实用技巧:在 HAL 代码中增加自定义 TAG,例如
#define LOG_TAG "CameraHAL_ISP",然后在 logcat 中过滤 adb logcat -s CameraHAL_ISP,可以快速隔离特定模块的日志。
2.3.2 dmesg:内核态问题的“黑匣子”
当 HAL 层问题涉及驱动、DMA、IOMMU、内存分配时,logcat 往往无能为力,此时必须查看 dmesg:
# 1. 实时监控内核日志
adb shell dmesg -w | grep -E "camera|isp|iommu|v4l2"
# 2. 查看历史内核日志(带时间戳)
adb shell dmesg -T | grep -E "camera|hal"
# 3. 捕获 OOM killer 信息
adb shell dmesg -T | grep -E "Out of memory|oom_kill"
# 4. 捕获 IOMMU 错误(常见于 buffer 问题)
adb shell dmesg -T | grep -E "iommu|page fault"
| dmesg 关键字 | 典型含义 | 关联 HAL 问题 |
|---|---|---|
iommu page fault |
IOMMU 页错误,HAL 传递了无效物理地址 | buffer 未正确锁定或已释放 |
Out of memory |
系统内存耗尽,可能触发 OOM killer | HAL 内存泄漏导致系统级崩溃 |
watchdog bite |
硬件看门狗超时,HAL 长时间未响应 | HAL 死锁或死循环 |
v4l2 ioctl timeout |
V4L2 驱动调用超时 | HAL 与驱动通信异常 |
2.3.3 tombstone:Crash 的“尸检报告”
当 native 进程(如 cameraserver)发生 Crash 时,系统会自动生成 tombstone 文件,记录崩溃时的完整上下文:
# 1. 查看 tombstone 文件列表
adb shell ls -l /data/tombstones/
# 2. 拉取最新的 tombstone 到本地
adb pull /data/tombstones/tombstone_XX ./tombstone_analysis.txt
# 3. 使用 ndk-stack 解析堆栈(需要符号表)
adb pull /data/tombstones/tombstone_XX ./tombstone_raw.txt
ndk-stack -sym ./out/target/product/xxx/symbols -dump ./tombstone_raw.txt
tombstone 文件的核心分析字段:
| 字段 | 示例 | 分析要点 |
|---|---|---|
| signal | signal 11 (SIGSEGV), code 1 (SEGV_MAPERR) |
段错误,通常为空指针或野指针 |
| fault addr | fault addr 0x00000000 |
访问地址为 0,几乎可以确定是空指针解引用 |
| backtrace | #00 pc 00012345 /vendor/lib/hw/camera.xxx.so |
崩溃时的函数调用栈,需用 ndk-stack 解析为源码行号 |
| memory map | ... [anon:gralloc_buffer] |
查看崩溃地址附近的内存映射,判断是否 buffer 相关 |
关键提醒:tombstone 文件是“一次性”的——每次 Crash 会覆盖上一个文件。在压力测试中,如果连续 Crash,务必在每次 Crash 后立即拉取 tombstone,或者使用
adb shell cp /data/tombstones/tombstone_XX /data/tombstones/backup_$(date +%s) 进行备份。
2.4 实战:一次典型的稳定性问题定位流程
将上述工具链串联起来,形成标准化的定位流程:
- 触发问题:运行压力测试脚本(如连续 1000 次预览+拍照循环)。
- 观察现象:测试过程中 cameraserver 进程消失,相机应用黑屏。
- 收集 logcat:搜索
fatal或signal,找到 Crash 前的最后日志。 - 拉取 tombstone:从
/data/tombstones/获取最新文件,查看 backtrace。 - 检查 dmesg:确认是否有 IOMMU 错误或 OOM 信息。
- 交叉验证:logcat 显示
CameraHAL: processCaptureRequest failed,tombstone 显示#00 camera.xxx.so: ReleaseBuffer,dmesg 显示iommu page fault→ 定位为 buffer 释放后仍被访问。
本章小结:稳定性测试的基础在于“定义清晰、环境可控、工具熟练”。无 Crash/无 ANR/无内存泄漏是三大硬指标;adb + root + 性能模式是标准环境;logcat/dmesg/tombstone 是定位问题的三把利刃。掌握这些基础,后续章节的压力测试设计和故障排查才有据可依。