Android稳定性-29-bugreport 怎么看:系统状态、服务状态与问题证据
bugreport 是 Android 稳定性问题里最接近系统全景的证据包。
它不是一个“很大的日志文件”,而是 dumpstate 在某一时刻收集到的系统状态、服务状态、历史日志、进程信息、资源信息和部分文件快照。
会看 bugreport,意味着能够从一堆章节里找到对问题结论有用的证据,而不是把压缩包直接转发。
这篇重点讲 bugreport 怎么看:先验证有效性,再找系统状态、服务状态和问题证据。
这篇文章按稳定性测试和问题闭环的视角展开,不追求把源码每一层都讲完,而是把测试同学、测试开发和一线定位人员真正会用到的路径讲清楚。
读完后至少应该能做到三件事:
- 看到现象后知道优先找哪类日志或报告。
- 能把命令、日志位置、关键字段和判断结论写进报告。
- 能识别常见误判,避免把环境问题、脚本问题和产品问题混在一起。
1、先确认 bugreport 是否有效
围绕“bugreport 分析”,首先要把问题从现象还原到可验证对象。
- bugreport 往往在问题发生后采集,现场可能已经变化。
- 报告内容巨大,盲目全文搜索会浪费时间。
- 不同 Android 版本和厂商定制会导致目录结构差异,需要抓住稳定入口。
稳定性工作最怕两个极端:一个极端是只看最终结果,另一个极端是把所有日志都丢给开发。
好的分析路径应该介于两者之间:先选入口,再补证据,最后给出边界清楚的判断。
| 分析层次 | 要回答的问题 | 典型输出 |
|---|---|---|
| 现象 | 用户或脚本看到了什么 | 截图、录屏、失败时间、设备序列号 |
| 入口 | 最先从哪类日志切入 | 关键字、文件路径、命令 |
| 证据 | 哪些字段支持判断 | 时间线、PID、线程、服务状态 |
| 结论 | 属于哪类问题 | 产品缺陷、环境异常、脚本问题、待确认 |
| 动作 | 下一步谁处理 | 责任模块、复现建议、补采材料 |
2、解压目录和主文件入口
分析 系统状态、服务状态和问题证据 时,先把日志和报告系统位置固定下来。
bugreport-DEVICE-BUILD-DATE.zipbugreport-*.txtdumpstate_board.txtFS/data/anr/FS/data/tombstones/FS/data/system/dropbox/main_entry.txtversion.txt
这些位置不要只作为附件目录,而要在报告系统里形成可点击、可搜索、可追溯的索引。
每个索引至少包含采集时间、设备序列号、测试 run_id、文件大小、生成阶段和保留期。
1 | artifact_index |
3、设备版本和采集时间
命令要写成可复用的标准入口,避免每个人临时发挥导致字段缺失。
1 | adb bugreport bugreport.zip |
建议所有稳定性任务都记录命令版本。命令参数变化会直接影响日志完整性,例如 buffer 选择、时间格式、是否包含 crash buffer。
| 命令目标 | 必须保留的信息 | 缺失后的风险 |
|---|---|---|
| 设备识别 | serial、型号、系统版本、构建指纹 | 无法判断是否同一设备或同一版本 |
| 时间对齐 | 设备时间、主机时间、测试阶段时间 | 无法建立问题窗口 |
| 异常入口 | 关键字、PID、TID、tag | 只能凭感觉猜测根因 |
| 系统状态 | 服务 dump、资源指标、DropBox | 无法证明系统侧是否异常 |
4、系统属性与构建信息
这一部分关注 bugreport 分析 中最容易被忽略的环节:系统属性与构建信息。
分析时建议按“输入、处理、输出、异常、责任边界”五个点拆开。
| 拆解点 | 要看什么 | 落地建议 |
|---|---|---|
| 输入 | 测试参数、设备状态、版本信息 | 进入任务前固化快照 |
| 处理 | 脚本阶段、系统服务状态、日志采集过程 | 用事件流记录阶段变化 |
| 输出 | 报告、附件、指标、缺陷单 | 统一 run_id 和路径规则 |
| 异常 | Crash、ANR、Watchdog、离线、超时 | 按异常类型自动分类 |
| 边界 | 测试平台、系统版本、应用模块、环境因素 | 结论里写清楚排除项 |
实践中不要等到问题发生后再补字段。稳定性问题很多是一次性的,现场被覆盖后再想补采会非常被动。
- 字段要机器可读,也要人能理解。
- 证据路径要稳定,不要依赖个人电脑目录。
- 结论要可追问,不能只写“疑似系统问题”。
- 无法判断时明确写缺口,不要把猜测包装成事实。
5、ActivityManager 状态怎么看
结构化字段比散落文字更重要。字段设计不好,后面的筛选、趋势、去重和问题闭环都会变成手工活。
| 字段 | 含义 | 示例 | 用途 |
|---|---|---|---|
| run_id | 一次执行的唯一标识 | stability-20260305-001 | 串联任务、设备、日志和报告 |
| serial | 设备序列号 | R58N000000A | 定位设备维度问题 |
| build_fingerprint | 系统构建指纹 | vendor/device/release-keys | 确认版本一致性 |
| event_type | 异常类型 | java_crash/anr/watchdog/native_crash | 分类统计和路由 |
| event_time | 异常发生时间 | 2026-03-05 23:17:44.321 | 切日志窗口 |
| evidence_path | 证据路径 | artifacts/run/logcat.txt | 复盘跳转 |
| owner_hint | 初步归属 | app/framework/native/vendor/kernel | 分派处理 |
字段不是越多越好。真正要保留的是能支撑判断、复现、归属和趋势分析的信息。
6、WindowManager 状态怎么看
结构化字段比散落文字更重要。字段设计不好,后面的筛选、趋势、去重和问题闭环都会变成手工活。
| 字段 | 含义 | 示例 | 用途 |
|---|---|---|---|
| run_id | 一次执行的唯一标识 | stability-20260305-001 | 串联任务、设备、日志和报告 |
| serial | 设备序列号 | R58N000000A | 定位设备维度问题 |
| build_fingerprint | 系统构建指纹 | vendor/device/release-keys | 确认版本一致性 |
| event_type | 异常类型 | java_crash/anr/watchdog/native_crash | 分类统计和路由 |
| event_time | 异常发生时间 | 2026-03-05 23:17:44.321 | 切日志窗口 |
| evidence_path | 证据路径 | artifacts/run/logcat.txt | 复盘跳转 |
| owner_hint | 初步归属 | app/framework/native/vendor/kernel | 分派处理 |
字段不是越多越好。真正要保留的是能支撑判断、复现、归属和趋势分析的信息。
7、Package 和进程状态
结构化字段比散落文字更重要。字段设计不好,后面的筛选、趋势、去重和问题闭环都会变成手工活。
| 字段 | 含义 | 示例 | 用途 |
|---|---|---|---|
| run_id | 一次执行的唯一标识 | stability-20260305-001 | 串联任务、设备、日志和报告 |
| serial | 设备序列号 | R58N000000A | 定位设备维度问题 |
| build_fingerprint | 系统构建指纹 | vendor/device/release-keys | 确认版本一致性 |
| event_type | 异常类型 | java_crash/anr/watchdog/native_crash | 分类统计和路由 |
| event_time | 异常发生时间 | 2026-03-05 23:17:44.321 | 切日志窗口 |
| evidence_path | 证据路径 | artifacts/run/logcat.txt | 复盘跳转 |
| owner_hint | 初步归属 | app/framework/native/vendor/kernel | 分派处理 |
字段不是越多越好。真正要保留的是能支撑判断、复现、归属和趋势分析的信息。
8、CPU、内存和负载信息
这一部分关注 bugreport 分析 中最容易被忽略的环节:CPU、内存和负载信息。
分析时建议按“输入、处理、输出、异常、责任边界”五个点拆开。
| 拆解点 | 要看什么 | 落地建议 |
|---|---|---|
| 输入 | 测试参数、设备状态、版本信息 | 进入任务前固化快照 |
| 处理 | 脚本阶段、系统服务状态、日志采集过程 | 用事件流记录阶段变化 |
| 输出 | 报告、附件、指标、缺陷单 | 统一 run_id 和路径规则 |
| 异常 | Crash、ANR、Watchdog、离线、超时 | 按异常类型自动分类 |
| 边界 | 测试平台、系统版本、应用模块、环境因素 | 结论里写清楚排除项 |
- 字段要机器可读,也要人能理解。
- 证据路径要稳定,不要依赖个人电脑目录。
- 结论要可追问,不能只写“疑似系统问题”。
- 无法判断时明确写缺口,不要把猜测包装成事实。
9、DropBox 历史异常入口
分析 系统状态、服务状态和问题证据 时,先把日志和报告系统位置固定下来。
bugreport-DEVICE-BUILD-DATE.zipbugreport-*.txtdumpstate_board.txtFS/data/anr/FS/data/tombstones/FS/data/system/dropbox/main_entry.txtversion.txt
这些位置不要只作为附件目录,而要在报告系统里形成可点击、可搜索、可追溯的索引。
每个索引至少包含采集时间、设备序列号、测试 run_id、文件大小、生成阶段和保留期。
1 | artifact_index |
10、ANR、tombstone 和 Watchdog 证据
分析 系统状态、服务状态和问题证据 时,先把日志和报告系统位置固定下来。
bugreport-DEVICE-BUILD-DATE.zipbugreport-*.txtdumpstate_board.txtFS/data/anr/FS/data/tombstones/FS/data/system/dropbox/main_entry.txtversion.txt
这些位置不要只作为附件目录,而要在报告系统里形成可点击、可搜索、可追溯的索引。
每个索引至少包含采集时间、设备序列号、测试 run_id、文件大小、生成阶段和保留期。
1 | artifact_index |
11、Kernel、pstore 和重启原因
这一部分关注 bugreport 分析 中最容易被忽略的环节:Kernel、pstore 和重启原因。
分析时建议按“输入、处理、输出、异常、责任边界”五个点拆开。
| 拆解点 | 要看什么 | 落地建议 |
|---|---|---|
| 输入 | 测试参数、设备状态、版本信息 | 进入任务前固化快照 |
| 处理 | 脚本阶段、系统服务状态、日志采集过程 | 用事件流记录阶段变化 |
| 输出 | 报告、附件、指标、缺陷单 | 统一 run_id 和路径规则 |
| 异常 | Crash、ANR、Watchdog、离线、超时 | 按异常类型自动分类 |
| 边界 | 测试平台、系统版本、应用模块、环境因素 | 结论里写清楚排除项 |
- 字段要机器可读,也要人能理解。
- 证据路径要稳定,不要依赖个人电脑目录。
- 结论要可追问,不能只写“疑似系统问题”。
- 无法判断时明确写缺口,不要把猜测包装成事实。
12、把 bugreport 证据写进报告
分析 系统状态、服务状态和问题证据 时,先把日志和报告系统位置固定下来。
bugreport-DEVICE-BUILD-DATE.zipbugreport-*.txtdumpstate_board.txtFS/data/anr/FS/data/tombstones/FS/data/system/dropbox/main_entry.txtversion.txt
这些位置不要只作为附件目录,而要在报告系统里形成可点击、可搜索、可追溯的索引。
每个索引至少包含采集时间、设备序列号、测试 run_id、文件大小、生成阶段和保留期。
1 | artifact_index |
13、完整案例:黑屏问题的系统状态还原
结构化字段比散落文字更重要。字段设计不好,后面的筛选、趋势、去重和问题闭环都会变成手工活。
| 字段 | 含义 | 示例 | 用途 |
|---|---|---|---|
| run_id | 一次执行的唯一标识 | stability-20260305-001 | 串联任务、设备、日志和报告 |
| serial | 设备序列号 | R58N000000A | 定位设备维度问题 |
| build_fingerprint | 系统构建指纹 | vendor/device/release-keys | 确认版本一致性 |
| event_type | 异常类型 | java_crash/anr/watchdog/native_crash | 分类统计和路由 |
| event_time | 异常发生时间 | 2026-03-05 23:17:44.321 | 切日志窗口 |
| evidence_path | 证据路径 | artifacts/run/logcat.txt | 复盘跳转 |
| owner_hint | 初步归属 | app/framework/native/vendor/kernel | 分派处理 |
字段不是越多越好。真正要保留的是能支撑判断、复现、归属和趋势分析的信息。
14、常见误判
稳定性分析中的误判通常不是因为不会搜日志,而是因为证据边界没有写清楚。
| 误判 | 为什么会错 | 正确处理 |
|---|---|---|
| 只看最后一条错误 | 最后一条日志常常只是结果,根因可能在几秒到几分钟前。 | |
| 把 ERROR 当结论 | Android 日志里很多 ERROR 是降级路径,不一定对应用户可见故障。 | |
| 忽略设备时间 | 多机压测时不同设备时间漂移会导致时间线对不上。 | |
| 只交附件不写判断 | 稳定性问题需要给出入口、证据、推断和待确认点。 | |
| 把脚本失败算系统失败 | 先排除 adb 断连、电脑休眠、权限弹窗、网络异常。 | |
| 用单次复现率推整体风险 | 稳定性问题要看版本、机型、场景、持续时长和样本量。 |
- bugreport 采得越晚越完整:越晚越可能丢失现场。
- 只搜应用包名:系统问题可能不包含应用包名。
15、检查清单
下面这份清单适合放到报告系统、缺陷模板或复盘 SOP 里。
- 是否记录设备序列号、版本、测试场景和 run_id
- 是否有明确的问题发生时间,精确到秒或毫秒
- 是否保留原始日志,避免只保留截图
- 是否说明首选分析入口和关键字
- 是否切出问题前后时间窗口
- 是否关联 PID、TID、进程名或服务名
- 是否检查设备离线、低电量、重启、存储不足等环境因素
- 是否区分产品缺陷、平台脚本失败和采集失败
- 是否有完整附件路径和校验信息
- 是否写明初步归属和待开发确认的问题
- 是否给出复现步骤或压测参数
- 是否说明本次结论的证据边界
- 是否把重复问题合并到已有缺陷
- 是否把无法判断的问题标记为需要补采
16、输出物模板
输出物模板要让读者不用重新翻日志,也能理解判断依据。
1 | 问题标题:[bugreport 分析] <设备>/<版本>/<场景> 发生 <现象> |
17、小结
bugreport 分析 的核心不是堆材料,而是让材料形成可验证的判断。
可以把本文方法压缩成一句话:
先从现象选择入口,再用命令和日志位置锁定证据,最后把 系统状态、服务状态和问题证据 放进报告闭环。
当报告能明确写出时间、设备、入口、证据、归属和待确认项时,稳定性测试才真正从“发现问题”走向“推动解决问题”。
附录:一线排查口径
下面这些口径适合直接放到团队内部 SOP 中,用来统一不同同学的分析输出。
- 先记录现象,不要先写归因。
- 先确认时间,不要从全文第一行开始翻。
- 先找异常入口,再扩展上下文。
- 先判断日志是否覆盖现场,再判断问题原因。
- 先排除采集和环境问题,再升级产品缺陷。
- 先看直接证据,再引用辅助指标。
- 先写确定事实,再写推断。
- 先描述当前版本,再做跨版本对比。
- 先保留原始附件,再生成摘要。
- 先给出复现参数,再讨论概率。
- 先确认责任边界,再分派缺陷。
- 先定义修复验证方法,再关闭问题。
附录:报告字段建议
| 字段 | 说明 |
|---|---|
| project | 项目名 |
| version | 版本号 |
| build_fingerprint | 系统构建指纹 |
| app_version | 应用版本 |
| run_id | 测试运行 ID |
| job_id | 任务 ID |
| serial | 设备序列号 |
| model | 设备型号 |
| android_version | Android 版本 |
| scenario | 测试场景 |
| tool | 压测工具 |
| tool_version | 工具版本 |
| start_time | 开始时间 |
| end_time | 结束时间 |
| event_time | 异常时间 |
| event_type | 异常类型 |
| process | 进程名 |
| pid | 进程 ID |
| tid | 线程 ID |
| thread_name | 线程名 |
| first_keyword | 首个关键字 |
| time_window | 分析窗口 |
| artifact_path | 附件路径 |
| owner_hint | 归属建议 |
| risk_level | 风险等级 |
| dedupe_key | 去重键 |
| issue_id | 缺陷单 |
| verify_plan | 验证方案 |
附录:逐步分析 SOP
下面把 bugreport 分析 拆成一套可以直接执行的 SOP。它的目标不是替代经验,而是让不同成员在同一类问题上产出一致的证据结构。
确认对象:确认本次分析对象是 系统报告,不要把相邻任务或其它设备的日志混入。
确认版本:记录 build fingerprint、应用版本、脚本版本和平台版本。
确认时间:把用户时间、设备时间、主机时间和报告时间放到同一张时间线上。
确认范围:明确是单设备、单场景、单进程问题,还是多设备、多场景共性问题。
确认附件:检查 logcat、bugreport、tombstone、traces、截图、录屏和指标是否齐全。
确认完整性:检查附件大小、采集时间、截断情况和是否覆盖问题窗口。
选择入口:围绕 dumpstate、dumpsys、DropBox、CPU、memory、kernel log 选择第一个分析入口。
切出窗口:以异常发生时间为中心,先看前后 2 到 5 分钟,再按需要扩大。
提取关键字:提取能说明异常类型的第一组关键字,而不是提取所有 ERROR。
关联实体:关联 PID、TID、进程名、线程名、服务名、包名和设备序列号。
补充上下文:向前找触发动作,向后找系统处理结果。
排除环境:排除 adb offline、低电量、存储满、电脑休眠、网络断开等因素。
排除脚本:排除脚本超时、元素定位失败、权限弹窗和测试数据污染。
确定类型:把问题归入 Java Crash、Native Crash、ANR、Watchdog、重启、卡顿、离线或环境异常。
寻找直接证据:找到能直接支持问题类型的日志行、报告章节或线程栈。
寻找辅助证据:用 CPU、内存、温度、进程状态或服务状态补强结论。
描述边界:写清楚当前证据能证明什么,不能证明什么。
给出归属:先给 owner_hint,再让对应模块确认最终归属。
提出补采:如果证据不足,明确下一轮要多抓什么。
定义验证:写清楚修复后用什么版本、设备、场景和时长验证。
附录:样例时间线
时间线是 bugreport 分析 的骨架。没有时间线,日志只能证明“出现过某些现象”,不能证明“这些现象之间存在关系”。
| 时间 | 来源 | 事件 | 分析意义 |
|---|---|---|---|
| 22:10:00.000 | test_runner | 开始场景:高频切换页面 | 确定压测阶段 |
| 22:10:13.421 | logcat | 目标进程输出关键状态 | 确认应用仍在响应 |
| 22:10:39.802 | events | am_proc_died 或 am_anr 相关事件 | 定位系统感知时间 |
| 22:10:41.128 | logcat | 异常关键字首次出现 | 定位首个异常入口 |
| 22:10:42.600 | artifact | 生成 tombstone/traces/bugreport | 确认证据采集点 |
| 22:10:49.000 | runner | 脚本判定失败并停止动作 | 区分脚本失败和系统失败 |
| 22:12:10.000 | report | 自动生成报告摘要 | 进入问题闭环 |
写时间线时要避免把采集时间当发生时间。bugreport 的生成时间、traces 的 dump 时间、logcat 中异常首次出现时间,含义并不相同。
附录:证据强弱分级
| 证据等级 | 例子 | 可以支持的结论 | 不能支持的结论 |
|---|---|---|---|
| 强证据 | 明确异常关键字、线程栈、signal、Watchdog blocked 信息 | 可以支持问题类型和初步归属 | 不能替代源码级根因 |
| 中证据 | CPU 飙高、内存紧张、服务状态异常 | 可以支持诱因或环境背景 | 不能单独证明崩溃根因 |
| 弱证据 | 截图、用户描述、脚本超时 | 可以支持现象存在 | 不能单独归因 |
| 反证 | 无 tombstone、无 kernel panic、无 adb offline | 可以排除某些方向 | 不能证明另一个方向一定成立 |
报告里要明确证据等级。把弱证据写成强结论,是稳定性报告最常见的质量问题之一。
附录:复盘会议提纲
- 这次失败是否覆盖目标版本、目标机型和目标场景。
- 失败样本是否集中在某台设备、某个时间段或某个脚本动作。
- 异常入口是由系统发现、应用发现,还是测试平台发现。
- 是否存在重复问题,去重依据是什么。
- 是否有足够证据区分产品缺陷和环境异常。
- 是否需要补采更高权限日志或开启更多 debug 开关。
- 是否影响发版阻塞条件。
- 修复后验证需要多少设备、多少时长、哪些场景。
- 报告系统是否暴露了采集、索引或分类能力缺口。
- 下一轮测试是否要调整压测模型。
附录:面向缺陷单的最小摘要
缺陷单摘要不要复制整篇报告。它应该只保留开发判断所需的最小证据。
1 | 类型:bugreport 分析 |
附录:质量门禁建议
| 等级 | 条件 | 处理建议 |
|---|---|---|
| P0 | Watchdog、系统重启、可稳定复现 Native Crash、核心路径必现 ANR | 默认阻塞发版 |
| P1 | 高频 App Crash、低概率但影响核心功能的 ANR、持续资源泄漏 | 需要评审风险 |
| P2 | 低频边缘场景失败、可恢复问题、脚本可规避问题 | 进入遗留风险列表 |
| 环境 | 设备离线、线缆异常、电脑休眠、测试账号异常 | 不计产品失败,但要计平台质量 |
对于 bugreport 分析,门禁规则必须和证据质量绑定。没有证据链的 P0 会浪费团队精力,没有门禁的严重问题会被通过率掩盖。
附录:交付前自检问题
- 我能否用一句话说明这篇报告的结论。
- 我能否指出结论依赖的三条最关键证据。
- 我是否保留了原始日志,而不是只保留加工后的摘要。
- 我是否写清楚了无法确认的部分。
- 我是否避免把“可能”写成“确定”。
- 我是否把复现条件写到别人可以重新执行。
- 我是否把附件路径写到别人可以直接打开。
- 我是否把环境失败从产品失败里拆出来。
- 我是否检查过同一问题是否已有缺陷单。
- 我是否给出了修复后的验证标准。