Uninote
Uninote
用户根目录
brdr
common
programming
docs
tests
后端试题
问题讨论

Android 窗口系统阻塞复现检查

结论

已复现同类系统窗口阻塞。 等搜索测试结束后,独占设备复测在第 17 轮重启时触发。 新的系统转储再次显示任务快照调用 captureLayersSync,窗口管理锁被占用, 窗口、显示、动画线程阻塞 60 秒,随后 watchdog 终止 system_server。

这是本次独占测试 17 次尝试中的一次故障,不能据此估计稳定发生概率。 未完成原计划的 60 轮;确认同类故障后停止注入并保存证据。

后续频率复测另做 3 批,共 73 次尝试,没有再次出现目标 watchdog,详见下一节。

后续复现频率检查

2026-10-25 10:30:13–10:43:16(Asia/Shanghai)执行 3 批测试,原计划每批最多 30 轮。 每批从同一 AVD 冷启动,使用上面记录的同一 APK,操作顺序和等待间隔保持一致。 不输入或保存笔记,不重装 APK,不调整 GPU 配置,也不运行其他设备测试。

批次 尝试轮数 完整通过 目标系统 watchdog 其他中断
1 13 12 0 第 13 轮重启后,编辑模式恢复等待超过 25 秒
2 30 30 0 无
3 30 30 0 无
本次合计 73 72 0 1 次恢复等待超时
  • 本次目标异常的观测计数为 0 / 73 次尝试,0 / 3 批;不能解释为不会再发生。
  • 若与前面的独占复现合计,则为 1 / 90 次尝试(约 1.1%),4 批中 1 批发生。
    • 这只是已观察到的次数比例,不是稳定故障概率。
    • 前次复现开始时模拟器已运行较久,本次各批冷启动,运行时长和缓存状态不同。
    • 批内循环并非独立随机样本,第一批又因另一类异常提前停止,不据此计算置信区间。
  • 两批各 30 轮未触发,说明不能将前次第 17 轮当作固定触发阈值。
  • 72 个完整轮次的重启后界面树读取最大耗时 3.8375 秒,完整流程最大耗时 15.0879 秒。
  • 72 个完整轮次都核对编辑器全文和磁盘文件与原基线一致。
  • 测试结束后另冷启动一次模拟器,恢复核对通过:正文 1,159 字符、磁盘文件 1,118 字节与原基线一致, 安装包 SHA-256 未变;结束时应用可正常使用。

第一批的独立等待超时

  • 第 13 轮的 am force-stop 在 10:31:58.747 发起,随后立即 am start。
  • 25 秒内界面树未出现选中的“编辑”节点,脚本停止该批,保留原始 XML。
    • XML 中无法读取到应用的笔记控件;没有足够证据将其直接认定为应用启动死锁。
  • 脚本退出后继续保留约 90 秒系统诊断窗口,没有目标 WATCHDOG KILLING SYSTEM PROCESS。
  • dumpsys window 正常返回;dumpsys activity lastanr 为 <no ANR has occurred since boot>。
  • 没有新增 /data/anr/ 转储,未见与前次相同的系统 watchdog 证据。
  • 此轮计入尝试总数,单独报告为恢复等待超时,不计为目标窗口阻塞,也不计为完整通过。
  • 更早的准备阶段曾因冷启动恢复为预览模式而等待编辑模式超时,尚未进入循环,未计入上述 73 轮。
    • 准备步骤改为显式切到编辑模式;循环内不更改等待间隔或补点按钮。

频率检查证据

  • 提交保留的频率汇总包含逐批结果和恢复核对。
  • 临时脚本:build/qa-window-repro/frequency.py,复用项目 test/ui/driver.py。
  • 原始目录:build/qa-window-repro/frequency/。
    • batch-1/ 至 batch-3/:status.json、actions.jsonl、console.txt、logcat.txt、restart-*.xml。
    • 第一批另有 window-timeout.txt、lastanr-timeout.txt 和后续窗口/ANR 记录。
    • 三批日志均未出现 Unexpected EOF,采集窗口内未检出目标 watchdog,未生成新的 ANR 转储。
    • summary.json:最终汇总;recovery/:最后一次冷启动后的实际界面和核对日志。
    • analyze.txt、flutter-test.txt:频率检查结束后执行的验证,避免增加设备测试期间的宿主负载。
  • 只覆盖当前 Debug 模拟器及这条重启流程;没有重跑整小时混合随机操作或真机测试。

独占设备复测

  • 另一项搜索测试进程结束后开始,操作时间为 Asia/Shanghai。
  • 固定 APK SHA-256:BD5CE1D0A10A6518E25D53F986AAF77A8E9BFF06D315E5D4381387501B1C83E3。
    • 为包含搜索修复的新安装包,与 10 月 24 日报告的 APK 不同。
    • 测试前包记录 lastUpdateTime=2026-10-25 02:06:49(UTC),期间本次没有安装操作。
  • 独占测试使用同一 AVD、测试库和下文的前后台切换/重启流程。
  • 前 16 轮完整通过,每轮编辑器全文和磁盘内容与基线一致。
  • 第 17 轮:
    • 10:12:53.812:按 HOME。
    • 10:12:54.376:am start 返回应用,10:12:56.471 的界面树读取仅 0.0765 秒。
    • 10:12:57.765:am force-stop;10:12:57.819 紧接着 am start。
    • 此后未取得恢复为编辑模式的记录,测试 RPC 未正常完成。
    • 10:13:16.558:WAITED_UNTIL_PRE_WATCHDOG。
    • 10:14:09.860:WATCHDOG KILLING SYSTEM PROCESS,报告三个系统线程阻塞 60 秒。
    • 原 system_server PID 为 587,后续 PID 为 6890;系统服务随后仍未恢复。
  • 新转储的关键链路与原故障一致:
    • android.anim 持有 WindowManagerGlobalLock,位于任务快照的 captureLayersSync。
    • watchdog.monitor、android.display 等线程等待该锁。
    • SurfaceFlinger 主线程等待 BpComposerClient::executeCommands。
  • 故障后 dumpsys dropbox 返回 Can't find service: dropbox,截图命令设置 8 秒超时后未生成图片。
  • 完整保存新 watchdog / pre-watchdog 原始转储后,主动停止本次测试进程并重启模拟器恢复环境。
    • 通过 adb root 读取只允许系统账户访问的 /data/anr/,未修改设备数据或图形配置。
    • adb reboot 后仍等待 SurfaceFlinger 服务;adb emu kill 未能关闭宿主进程。
    • 最终停止该 AVD 的宿主进程,用 -avd t1 -no-snapshot-load 冷启动,未清除数据或更改 GPU 配置。
    • 模拟器启动完成后重新启动应用,恢复核对通过:编辑器全文 1,159 字符与故障前相同, 磁盘文件 1,118 字节与重启前相同,APK SHA-256 未改变。

提交保留的关键证据:watchdog 日志与系统线程栈。 完整原始证据位于 build/qa-window-repro/exclusive/:

  • actions.jsonl、console.txt:逐轮时序及 16 轮通过记录。
  • logcat.txt:本次系统 watchdog 及 system_server 重启过程。
  • pre-watchdog-anr.txt:10:13:16 的预警转储。
  • watchdog-anr.txt:10:14:01 开始收集的 60 秒阻塞转储。
  • recovery-pre-watchdog-anr.txt:新系统进程仍阻塞的后续转储。
  • recovery-checks.json、recovery-final/:完整重启模拟器后的正文、磁盘和安装包核对。

首次受干扰的尝试

首次尝试未复现原报告中的 89.50 秒窗口阻塞,但存在并行设备操作,不能判定问题已排除。 共完成 7 轮“前后台切换 → 强制停止并立即启动”,第 8 轮期间主动停止本次测试进程以避免干扰另一项测试。

  • 第 1、2 轮完成时未发现 APK 重装,重启后界面树读取分别为 4.7697 秒和 5.1223 秒。
  • 第 3 轮期间,另一项搜索修复测试在同一设备重装 APK,并操作应用。
    • Android 包记录的 lastUpdateTime 从 2026-10-24 13:45:57 变为 2026-10-25 02:06:49。
    • 包记录使用 Android 系统时间 UTC;对应本地时间为 10:06:49。
    • 第 3–7 轮受环境干扰,不能视为固定 APK、独占设备条件下的复测结果。
  • 7 轮均核对编辑器全文和测试笔记磁盘内容不变。
  • 7 轮重启后的单次界面树读取最大耗时为 5.1651 秒;完整工作流最大耗时为 32.5991 秒。
    • 完整工作流还包含前后台切换、启动等待、截图和内容核对,不等同于窗口阻塞时长。
  • 停止后与测试前相比,没有新增 system_server_pre_watchdog 或 system_server_watchdog 条目。
  • dumpsys activity lastanr 返回 <no ANR has occurred since boot>。

该阶段单独保留,不计入上面的独占测试结果。 原始报告:一小时深入随机模拟器测试。

环境与操作

  • 设备:emulator-5554,AVD t1,Android 15 / API 35,x86_64。
  • 系统指纹与原报告一致: Android/sdk_phone64_x86_64/emu64x:15/AE3A.240806.019/12368160:userdebug/test-keys。
  • 复用原测试库 b2f67a42f3a58ae388c95efbf5a8740a 的 preview.md,切到编辑模式。
  • 每轮按 HOME,等待 500 ms,执行 am start,等待编辑模式恢复,再等待 1 秒。
  • 执行 am force-stop,紧接着 am start,通过 uiautomator2 读取界面树并等待编辑模式恢复。
  • 每轮核对编辑器完整正文及 run-as 读取的已保存文件。
  • 首次尝试未输入或保存笔记、清除应用数据、构建安装 APK 或重启模拟器。
    • 测试期间发生的 APK 安装来自另一项搜索修复测试。
  • 本次测试首条完成记录为 10:06:17;操作记录使用 Asia/Shanghai。

原始故障转储复核

复核 build/qa-hour/system-pre-watchdog.txt 后,原报告中的系统阻塞判断仍有依据:

  • android.anim 持有 WindowManagerGlobalLock,调用任务快照的 TaskSnapshotController.recordSnapshot。
  • 该线程在 BpSurfaceComposer::captureLayersSync 中等待 Binder 返回。
  • watchdog.monitor 和 android.display 等线程等待同一窗口管理锁。
  • SurfaceFlinger 的截图 Binder 线程等待主线程提供显示和图层快照。
  • SurfaceFlinger 主线程位于 presentAndGetReleaseFences → BpComposerClient::executeCommands。

据此可推断阻塞链路延伸到模拟器显示合成服务,不能归为普通 Dart 异常。 现有栈只说明等待关系,不能确定图形服务、宿主 GPU 或其他环节中的最终根因。

验证与证据

  • flutter analyze:1 条既有 info,test/mp3_refresh_view_test.dart:37:11 缺少花括号。
  • flutter test:379 项通过。
    • 静态及单元测试检查了当时工作区,也包含另一项搜索修复的未提交改动;不代表安装包验证。
    • 检查在设备测试初期并行运行,对宿主负载可能有影响。
  • 临时复现脚本及逐轮记录:build/qa-window-repro/repro.py、actions.jsonl、console.txt。
  • 系统记录:dropbox-before.txt、dropbox-paused.txt、lastanr-before.txt、lastanr-paused.txt。
  • 界面树:同目录 restart-*.xml;静态和单元检查输出:analyze.txt、flutter-test.txt。
  • logcat.txt 在 APK 重装时段出现 Unexpected EOF,日志流不完整;未以此证明全程无异常。
  • 以上原始文件位于忽略的 build/ 下;flutter clean 会删除,本次没有执行清理。

同一环境重复前后台切换并立即重启可以再次触发,但尚不能保证第几次发生。 本轮没有重跑完整一小时随机序列,也未覆盖真机或其他 Android 系统版本,未修复图形链路根因。

2026-10-24-random-1h

2026-10-27-file-locate

点赞(0) 阅读(14) 举报
目录
标题