Skip to content

[Bug] 升级后 GUI 闪退:runtime handoff 因 PID 复用陷入死循环 #1268

Description

@Deepfriedmonkey-9527

Summary / 问题概述

从 0.2.37 升级到 0.3.7 后,Kun GUI 无法正常启动。打开后短暂显示"有后台存在",随即窗口消失、进程退出。重装软件无法修复。

根因是 ~/.kun/data/runtime.json 中记录的旧运行时 PID 已被 Windows 系统回收并分配给无关进程,而 update-handoff 模块在停止旧运行时前不校验 PID 归属,导致 handoff 必然失败且无降级路径,形成死循环。

Steps to reproduce / 复现步骤

1.安装 Kun 0.2.37,正常使用,运行时进程 A 监听在某端口(如 PID 15016, port 25062)
2.Kun 自动下载 0.3.7 更新并触发安装,新版本文件部署到安装目录,build ID 从 dc2ddd696ec8 变为 4d51719d6435
3.安装过程中或安装后,旧运行时进程 A 退出(可能因安装器替换文件导致),但 ~/.kun/data/runtime.json 仍记录着 PID 15016 的连接信息
4.Windows 将 PID 15016 回收并分配给系统服务 WMIRegistrationService.exe
5.用户启动 Kun GUI
此时 GUI 进入 handoff 流程:检测到磁盘 build(4d51719d6435)与 runtime.json 中的 build(dc2ddd696ec8)不一致,尝试停止旧运行时(PID 15016 / port 25062)。由于该 PID 已不属于 Kun,停止请求失败,GUI 直接退出。

Expected behavior / 期望行为

1.update-handoff 在 stop-runtimes 阶段应校验目标 PID 是否仍属于 Kun 运行时(如检查进程可执行文件路径、或向 port 发 /health 请求校验 instanceId)
2.若 PID 已不属于 Kun(进程不存在、或进程非 Kun),应视为旧运行时已自然退出,清除 runtime.json 后继续启动新版本
3.handoff 失败后应有降级路径,而非直接放弃启动——至少允许以当前磁盘 build 启动
4.gui-version-state.json 中的 pendingUpdate 在 handoff 失败时不应永久保留,避免每次启动都触发同样的失败流程
5.~/.kun/.data.kun-runtime-writer-claims/ 目录中存在非法文件名时,应跳过而非阻断启动

Actual behavior / 实际行为

1.GUI 向已被系统服务占用的 PID 15016 发送停止请求,收到 runtime_stop_failed,然后直接退出,不进入主界面
2.每次启动都重复同样的 handoff → stop-runtimes → failed → 退出循环,pendingUpdate 始终不被清除,升级永远无法完成
3.重装软件不能修复——因为 runtime.json 和 writer-claims 位于用户数据目录 ~/.kun/data/,不在安装目录内

Kun version / Kun 版本

0.3.7

Operating system / 操作系统

Windows 11 Insider Preview 26340.9233

Logs / 日志

1. GUI 日志:首次出现 handoff 失败(kun-2026-09-02.log)
9 月 2 日 15:43 UTC(北京时间 23:43)首次出现 installed-build-change + runtime_stop_failed:


[2026-09-02T15:43:32.400Z] [INFO] [startup] Desktop startup entered. - detail: {
  "platform": "win32",
  "packaged": true
}
[2026-09-02T15:43:32.599Z] [INFO] [update-handoff] Kun owner handoff discover - detail: {
  "reason": "installed-build-change",
  "phase": "discover",
  "elapsedMs": 0,
  "targetBuildId": "4d51719d6435"
}
[2026-09-02T15:43:32.601Z] [INFO] [update-handoff] Kun owner handoff discover - detail: {
  "reason": "installed-build-change",
  "phase": "discover",
  "elapsedMs": 2,
  "targetBuildId": "4d51719d6435",
  "probeClassification": "runtime-discovery-compatible"
}
[2026-09-02T15:43:32.601Z] [INFO] [update-handoff] Kun owner handoff quiesce-runtimes - detail: {
  "reason": "installed-build-change",
  "phase": "quiesce-runtimes",
  "elapsedMs": 2,
  "targetBuildId": "4d51719d6435"
}
[2026-09-02T15:43:33.119Z] [WARN] [update-handoff] Kun owner handoff stop-runtimes: failed — detail: {
  "reason": "installed-build-change",
  "phase": "stop-runtimes",
  "elapsedMs": 520,
  "targetBuildId": "4d51719d6435",
  "result": "failed",
  "code": "runtime_stop_failed",
  "ownerKind": "runtime",
  "flavor": "production",
  "pid": 15016,
  "instanceId": "e50571ea-0373-41fe-bd1e-1d626ac1fb82",
  "port": 25062,
  "buildId": "dc2ddd696ec83cf05bb7d420df2987e99fea42f97c6f4ab07153bc53ff8cd24c"
}
此日志之后无任何其他内容——GUI 直接退出,未进入主界面。

2. GUI 日志:次日反复启动失败(kun-2026-09-03.log)
9 月 3 日用户多次尝试启动,每次都重复同样的 handoff → stop-runtimes → failed 循环,共 7 次,间隔从几秒到几分钟不等:


[2026-09-03T12:22:58.647Z] [INFO] [startup] Desktop startup entered. - detail: {
  "platform": "win32",
  "packaged": true
}
[2026-09-03T12:22:58.877Z] [INFO] [update-handoff] Kun owner handoff discover - detail: {
  "reason": "installed-build-change",
  "phase": "discover",
  "elapsedMs": 0,
  "targetBuildId": "4d51719d6435"
}
[2026-09-03T12:22:58.880Z] [INFO] [update-handoff] Kun owner handoff discover - detail: {
  "reason": "installed-build-change",
  "phase": "discover",
  "elapsedMs": 3,
  "targetBuildId": "4d51719d6435",
  "probeClassification": "runtime-discovery-compatible"
}
[2026-09-03T12:22:58.880Z] [INFO] [update-handoff] Kun owner handoff quiesce-runtimes - detail: {
  "reason": "installed-build-change",
  "phase": "quiesce-runtimes",
  "elapsedMs": 3,
  "targetBuildId": "4d51719d6435"
}
[2026-09-03T12:22:59.524Z] [WARN] [update-handoff] Kun owner handoff stop-runtimes: failed — detail: {
  "reason": "installed-build-change",
  "phase": "stop-runtimes",
  "elapsedMs": 647,
  "targetBuildId": "4d51719d6435",
  "result": "failed",
  "code": "runtime_stop_failed",
  "ownerKind": "runtime",
  "flavor": "production",
  "pid": 15016,
  "instanceId": "e50571ea-0373-41fe-bd1e-1d626ac1fb82",
  "port": 25062,
  "buildId": "dc2ddd696ec83cf05bb7d420df2987e99fea42f97c6f4ab07153bc53ff8cd24c"
}

[2026-09-03T12:25:08.403Z] [INFO] [startup] Desktop startup entered.    ← 第 2 次尝试
[2026-09-03T12:25:08.993Z] [WARN] [update-handoff] stop-runtimes: failed — pid: 15016, code: "runtime_stop_failed"

[2026-09-03T12:25:19.102Z] [INFO] [startup] Desktop startup entered.    ← 第 3 次尝试
[2026-09-03T12:25:19.693Z] [WARN] [update-handoff] stop-runtimes: failed — pid: 15016, code: "runtime_stop_failed"

[2026-09-03T12:25:32.842Z] [INFO] [startup] Desktop startup entered.    ← 第 4 次尝试
[2026-09-03T12:25:33.432Z] [WARN] [update-handoff] stop-runtimes: failed — pid: 15016, code: "runtime_stop_failed"

[2026-09-03T12:25:40.523Z] [INFO] [startup] Desktop startup entered.    ← 第 5 次尝试
[2026-09-03T12:25:41.132Z] [WARN] [update-handoff] stop-runtimes: failed — pid: 15016, code: "runtime_stop_failed"

[2026-09-03T12:32:35.041Z] [INFO] [startup] Desktop startup entered.    ← 第 6 次尝试
[2026-09-03T12:32:35.893Z] [WARN] [update-handoff] stop-runtimes: failed — pid: 15016, code: "runtime_stop_failed"

[2026-09-03T12:33:06.110Z] [INFO] [startup] Desktop startup entered.    ← 第 7 次尝试
[2026-09-03T12:33:06.709Z] [WARN] [update-handoff] stop-runtimes: failed — pid: 15016, code: "runtime_stop_failed"
注意:每次 stop-runtimes 的 elapsedMs 在 440-650ms 之间,说明并非超时,而是请求被立即拒绝或返回错误。

3. 过期 runtime.json 内容

{
  "version": 2,
  "instanceId": "e50571ea-0373-41fe-bd1e-1d626ac1fb82",
  "pid": 15016,
  "startedAt": "2026-09-02T13:12:36.129Z",
  "host": "127.0.0.1",
  "port": 25062,
  "baseUrl": "http://127.0.0.1:25062",
  "runtimeToken": "7coozwoMWxPPh8fAhga8Y95QCrN2J7q4WtIwjs3Dqno",
  "insecure": false,
  "serviceVersion": "0.2.37",
  "buildId": "dc2ddd696ec83cf05bb7d420df2987e99fea42f97c6f4ab07153bc53ff8cd24c",
  "launchMode": "shared",
  "logPath": "C:\\Users\\cleve\\.kun\\data\\logs\\runtime.log"
}
该文件记录了旧版运行时(版本 0.2.37,PID 15016),但该 PID 此时已不属于 Kun 进程。

4. PID 归属验证

> tasklist | findstr 15016
WMIRegistrationService.ex    15016 Services                   0     16,184 K
PID 15016 已被 Windows 系统服务 WMIRegistrationService.exe 占用,与 Kun 无关。

5. 版本状态(升级未完成)

// %AppData%\Kun\gui-version-state.json
{
  "lastSeenVersion": "0.2.37",
  "pendingUpdate": {
    "version": "0.3.7"
  }
}
pendingUpdate 一直存在,说明 handoff 从未成功完成过,升级状态始终未推进。

6. writer-claims 残留文件

// ~/.kun/.data.kun-runtime-writer-claims/claim-42732-92c84687-8e3f-4e64-94b6-546b1c2d784d.json
{
  "schemaVersion": 1,
  "kind": "runtime",
  "pid": 42732,
  "token": "92c84687-8e3f-4e64-94b6-546b1c2d784d",
  "startedAt": "2026-09-02T13:12:17.728Z",
  "dataDir": "C:\\Users\\cleve\\.kun\\data"
}
PID 42732 同样已不存在。此残留文件在清理时若仅改后缀名(如 .stale)留在目录内,Kun 会因文件名格式校验失败而拒绝启动,报错如下:


[kun-gui] startup failed: Kun Runtime writer claim name is invalid:
  C:\Users\cleve\.kun\.data.kun-runtime-writer-claims\claim-42732-92c84687-8e3f-4e64-94b6-546b1c2d7

Checklist / 检查清单

  • I searched existing issues before opening this report. / 我已经搜索过现有 issue。
  • I removed sensitive information from logs and screenshots. / 我已经从日志和截图中移除敏感信息。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions