hermes desktop黑屏故障

一句话

不是单一故障,是「nix-ld 缺 Electron 运行库(已在世代层独立证实)」+「gateway 僵尸态重启循环」+「drkonqi 自身崩溃制造噪音」叠加。与克隆操作无因果关系——崩溃比克隆结束晚 26 分钟。而报告漏掉了最要紧的一条:克隆到盘1 的配置停在修复之前,盘1 启动后会原样复发。

时间线(实测,全部可追溯)

时刻事件证据来源
13:31 – 13:43:57克隆盘2→盘1,rsync 29.7 GB / 2,240,069 文件clone-disk1.log
13:39:13盘1 生成 gen48盘1 loader/entries
14:09:46 / 14:09:55 / 14:13:49 / 14:14:11 / 14:22:13Hermes 二进制 SIGILL ×5coredumpctl list
14:22:17drkonqi 列 coredump,自身也 SIGABRT用户 journal
14:22 – 14:26gateway「already owns this host」循环,restart counter → 29用户 journal
14:25:04configuration.nix 被改(补 nix-ld 库)文件 mtime
14:25:58gen47 = fix-hermes-desktop-black-after-clone-nixosprofile link
14:29:38重启/proc/uptime 反推
14:32:32desktop 启动,其后 0 崩溃ps + journal

逐条裁决:报告的 5 层根因

报告的判定裁决实测依据
层1:TMPDIR 残留 Windows 路径 C:\Users\cat\.hermes\tmp方向对,位置判错,且与本次崩溃无关~/.hermes/.env:530 与 profiles/nixos-u533b-u751f/.env:526 都已是 /home/cat/.hermes/tmp(mtime 分别 10-06、10-08,本次 sed 没动过它们)。Windows 路径只残留在 profiles/win10-u533b-u751f/.env:526。崩溃的 default profile 读的不是那个文件 → 该层不成立为本次病因,但是真隐患(切到 win10 profile 就会踩,会在 $HOME 下建出 ~/C:\Users\... 垃圾目录)
层2:node-pty 缺 C++ 编译链事实成立,归因不成立gcc/gnumake/python3/pkg-config 确在 configuration.nix 第 180 行;但 desktop 跑的是预编译包 ~/.hermes/hermes-agent/apps/desktop/release/linux-unpacked/Hermes(198 MB,mtime 10-06 22:56),不跑 npm ci → 与黑屏无因果
层3:nix-ld 缺 Electron 运行库 → SIGILL采信(已独立硬证实)逐世代对比 <system>/sw/share/nix-ld/lib:gen45/gen46 = 437 个库,缺 libGLX_mesa / libfontconfig / libgdk_pixbuf / libpulse;gen47 起 = 525 个,四个全在。这是版本层面可复现的证据,非推测
层4:GPU 子进程初始化失败现象采信,机制表述需修正Chromium/Electron 里的 SIGILL 不是「跳到非法指令」,而是 IMMEDIATE_CRASH()(x86 的 ud2)——代码主动触发的 CHECK / LOG(FATAL) 自杀。正确说法是「某处致命校验失败」,缺库或 GPU 初始化失败只是可能的触发条件之一;崩溃位于 --type=zygote,与「GPU 子进程」同类但不等价
层5:sandbox fallback 残留 + transient unit 残留部分采信 / 部分不可证transient unit 确实失败且至今未清:drkonqi-coredump-launcher@… ×3 仍 failed;windows-sandbox-fallback.json 当前是 {"state":"ok"},当时的旧值已无法回溯,此条不构成证据
「gateway 层有僵尸锁」采信(日志实锤)A gateway already owns this host … PID 1101 (launched by profile 'default'; serves: not published yet (its control socket has not answered)) 每 ~11 秒一次,restart counter is at 27…29;本次开机后 0 次
归因「因克隆而起」(你的重建标签写的是 after-clone-nixos)驳回克隆 13:43:57 结束,崩溃 14:09:46 起,相隔 26 分钟;且崩溃所处的 gen46 建于 12:32(早于克隆)。无因果证据。真实触发点已不可考——desktop 的 stderr 走了终端、没进 journal
「libglvnd 不能单独工作」/「drkonqi 崩溃是噪音」采信libglvnd 只是 dispatcher;实测 drkonqi-coredump-launcher 自身 SIGABRT ×6

报告漏掉的(本次新增,最要紧)

  1. 盘1 停在修复之前,启动后会原样复发。 克隆同步时刻 13:43:57,nix-ld 修复写入 14:25:04 → 盘1 的 /etc/nixos/configuration.nix 及其 gen48 不含那四个库,库数会是 437 而非 525。追平之前不要以主力身份启动它。
  2. 启动窗口内时钟错了 8 小时。date/timedatectl = 14:37 CST(RTC 06:37 UTC,正确),但本次开机的 journal 与 who -b 都记成 22:29/22:30,systemd 甚至显示 since 22:29:45; 7h left。事后靠日志复盘会踩这个坑。
  3. 残留 Windows 路径的确切位置:不在 default profile,在 profiles/win10-u533b-u751f/.env:526。
  4. desktop 不参与 Nix 构建:它是 git 安装目录下的预编译产物,所以「补编译链、重跑 npm ci」对它无效;真正的作用面只有 nix-ld 库集与进程启动环境变量。
  5. 另一处未清失败单元:app-trilium-notes@796a2c2a…service 仍 failed。

已验证有效的修复(按判据计)

动作生效判据(实测)
nix-ld 补 mesa / libGL / libGLU / fontconfig / freetype / gdk-pixbuf / libuuid / libpulseaudio / openssl库数 437 → 525;四个关键库自 gen47 起存在
重启系统desktop 进程环境实测 NIX_LD_LIBRARY_PATH=/run/current-system/sw/share/nix-ld/lib;14:32:32 启动后稳定运行、0 崩溃
gateway 侧处理本次开机 already owns this host = 0、Scheduled restart = 0
sandbox fallback 重置文件值为 {"state":"ok"}

下次同类故障的判据顺序

  1. coredumpctl list | grep -i Hermes —— 先拿信号与二进制路径。
  2. 信号是 SIGILL ⇒ 直接判为 Chromium IMMEDIATE_CRASH(主动自杀),别去找「非法指令」。
  3. ls $(readlink /nix/var/nix/profiles/system-N-link)/sw/share/nix-ld/lib | wc -l —— 逐世代比库数,最快最硬(本例 437 vs 525 一眼定案)。
  4. tr '\0' '\n' < /proc/<desktop 主进程>/environ | grep NIX_LD —— 看运行进程实际拿到什么,不看配置「应该」给什么。
  5. drkonqi 自身的 SIGABRT 全是噪音,忽略。

遗留待办

  • 把盘1 追平:同步 /etc/nixos + /nix,重建盘1 的 system 与引导条目 —— 否则盘1 首启会原样复发。
  • 清 profiles/win10-u533b-u751f/.env:526 的 Windows TMPDIR(属另一个 profile,需你点头)。
  • 时钟 8 小时偏差:查是否 RTC 被 Windows 写成本地时间导致启动瞬间读错。