Skip to content

adb server 起不来时留下原因;安卓开好而 adb 没登记上时补登记;补全组件挪目录被占时重试再复制 - #113

Merged
qiyinxi merged 4 commits into
ModAVD:mainfrom
qiyinxi:adb-boot-recover
Nov 9, 2026
Merged

qiyinxi merged 4 commits into
ModAVD:mainfrom
qiyinxi:adb-boot-recover

Conversation

@qiyinxi

@qiyinxi qiyinxi commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

为什么

有用户在一台装了安全软件的电脑上用 0.39.0 新建实例,连着四次失败:

  • 新建超时:管理器日志里,开机前后每 20 秒都在重起私有 adb server,一次也没监听上;中途起来过一次,模拟器启动后不到 15 秒又没了。可模拟器日志里安卓每次三四十到七十多秒就开好了。管理器等满 300 秒,报的却是「安卓没有启动完成」,至于 adb 为什么起不来,哪儿也没记。
  • 补全组件失败:Google Play 商店那 5 个文件刚写完一秒,把它们所在的目录挪进 sdk\playstore 就报拒绝访问,连着三次都这样。多半是有程序(安全软件扫刚写出的 APK)把文件开着没放。

用户那边的根本原因(谁让 adb 起不来、谁把它结束了)现在还查不到。这个 PR 做三件事:让这种情况下次能直接看出原因;能自己恢复的情况就恢复;挪目录被占时不再直接失败。

改了什么

  • adb server 的日志落盘,起不来时把原因报出来:
    • Env 里设了 ANDROID_ADB_LOG_PATH,私有、脚本两个 adb server 的日志都写进 logs\adb-server.log,不再混进 %TEMP%\adb.log。模拟器开机结束时自己调 adb、顺手起的 server 也写这里。日志超过 2 MB,下次起 server 前换成 .1。
    • server 起了、但在时限内没监听上:把这份日志的最后几行写进警告。内容一样的只报一次。
    • 本进程起来过的 server 不见了:报它是已经退出,还是还在但不再监听,附上日志最后几行。日志里没有退出原因、停在正常记录上,就是被外面结束的。
    • 问题包(问题包补收管理器日志、adb 进程与 adb server 日志、Windows 保留端口 #112 新加的「管理器日志」一节)也收 logs\adb-server.log 和它的 .1。文件不在就不提,旧版本的目录里没有这个文件。
  • 等开机时,安卓开好了、adb 却连不上:判断依据是模拟器写了 avd\mas_<i>.avd\bootcompleted.ini,而且这个文件不比 qemu 旧。模拟器启动时会删掉它,开机完成时再写出来。
    • 每 10 秒替这台实例向私有 adb server 登记一次(新加的 RegisterBooted)。模拟器只在开机结束时登记那一次;server 如果是之后才起来的或者重启过,就再也看不到这台实例。以前等开机时,对自己刚启动的实例从不重新登记。
    • 报告开机完成后 60 秒还连不上,就不再等,报「安卓已经开好了,但之后 N 秒里私有 adb 一直用不了」,并带上 adb 日志的最后一行。等满总时限时也这么报。
  • 补全组件挪目录:在 Windows 上把解好的目录挪进 sdk,遇到拒绝访问、共享冲突、锁冲突,先重试 30 秒;还不行,就把整棵目录复制过去,再删掉 staging。只有这一步会改用复制,因为源目录是我们自己的、删坏了也不要紧。把已有的目录挪开、失败后放回原处,都只重试、不复制。
    • TestFetchPutsOldDirBack 原来测的就是「文件被占着、挪不进去」,现在这种情况会改用复制装上。所以改成「复制也失败」再测放回旧目录,另加 TestFetchCopiesHeldDirIn 测改用复制能装上。

测试

  • 新加的单测:
    • adb:日志尾巴、轮转、Env、同样内容只报一次、发现 server 已退出或不再监听。
    • 开机等待:开机完成后会去登记、过 60 秒就停、到总时限时报的话,bootcompleted.ini 的新旧判断。
    • 挪目录:重试、改用复制、别的错误不重试、复制失败时不留半个目录。
  • 问题包:TestCollectManagerLogsAdbAndPorts 加上了 adb-server.log。
  • go test ./...;go vet(windows / darwin / linux)。
  • 开机主路径算核心改动,做了变异检查:11 条变异全被测试抓到(去掉登记、去掉 60 秒停止、开机完成时仍报普通超时、不看 bootcompleted.ini 的时间、不分错误类型都重试、没开 copyFallback 也复制、复制失败留下半个目录、每次都报、server 还在也报已退出、Env 不设日志路径、日志不轮转)。
  • 上机测试(一个测试根上的 6 GB 实例,headless):
    1. 正常开机:先结束这个根的私有 adb server,再 start。46 秒开好;logs\adb-server.log 有了,里面是 adb 37.0.1 的启动记录。
    2. 模拟用户的情况:开机过程中每 0.2 秒结束一次这个根的私有 adb server(只结束这个根自己 platform-tools\adb.exe 的进程),一直结束到 bootcompleted.ini 出现后 2 秒,让模拟器开机结束时那一次登记落空。结果 55 秒开好:
      • 补登记了两次,第一次碰上 server 又被结束了,第二次连上;
      • 每次 server 没了都报出 pid、什么时候起来的、日志最后几行(停在启动记录上,没有退出原因);
      • 之后正常关机。
  • 挪目录被安全软件占着这件事,本机复现不了,只有单测。

有用户新建实例时,私有 adb server 开机前后一直监听不上,安卓 72 秒就开好了,管理器却等满
300 秒才报「安卓没有启动完成」,原因无从查起;补全组件那边,Google Play 商店的目录刚写完
就挪不动(拒绝访问),连着三次都一样。

- 私有 adb server 的日志写到 logs\adb-server.log(Env 里设 ANDROID_ADB_LOG_PATH,模拟器
  自己调 adb 时起的 server 也写这里),超过 2 MB 起新 server 前换成 .1。
  - server 起了却没监听上:报出这份日志的最后几行;同样的内容只报一次。
  - 本进程起来过的 server 不见了:报它是已经退出,还是还在但不监听了,附上日志最后几行。
- 等开机时,模拟器报告安卓开机完成(avd\mas_<i>.avd\bootcompleted.ini 不比 qemu 旧),
  adb 却还连不上:
  - 每 10 秒替它向私有 adb server 登记一次(RegisterBooted)。模拟器只在开机结束时登记那
    一次,server 是那以后才起来或重启过的,就再也看不到这台实例。
  - 60 秒后仍连不上就不再等,报「安卓已经开好了,但私有 adb 一直用不了」,带上 adb 日志
    的最后一行;等满总时限时也这样报。
- 补全组件把解好的目录挪进 sdk 时,在 Windows 上遇到拒绝访问、共享冲突,重试 30 秒;还
  不行就复制过去再删 staging。只有挪进 sdk 这一步会复制,挪开已有目录、放回原处都只重试。
@qiyinxi
qiyinxi added this pull request to the merge queue Nov 9, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 9, 2026
@qiyinxi
qiyinxi added this pull request to the merge queue Nov 9, 2026
Merged via the queue into ModAVD:main with commit 7f95f40 Nov 9, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working platform:windows 与 Windows 平台相关

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant