5.4 KiB
WorkBuddy daemon 异常终止导致会话中断 · 取证报告
取证时间:2026-10-09 06:2x–06:4x(本地 UTC+8) 环境:win32 x64 / WorkBuddy 5.7.6 / Electron 37.10.3 / Node 22.21.1 / V8 13.8.258.32-electron.0 现象:后台自动化会话运行中途被判
terminated,未正常收尾,并遗留域锁未被释放 本报告全部结论取自日志与崩溃报告原文,可复现;未坐实的推断已单独标注
一、结论(三句)
1、daemon 进程内存在一分钟内涨近三倍(160MB → 444MB → 957MB,rss 1162MB)后被强制终止,日志里没有任何优雅退出或崩溃堆栈。
2、父进程随即拉起新一代 daemon(ppid 可证);旧 daemon 托管的 cli 子进程随之以退出码 1 结束,正在其上运行的会话被判 terminated。
3、本应拦截这一关的内存守护(guardian)全程失效 —— 它靠 wmic 采集进程指标,而本机 wmic 不存在,每 10 秒失败一次。
二、时间线(本地时间,取自 daemon.log 原文)
- 16:50:33(=本地次日 00:50:33)——
[DaemonMemWatch] pid=53940 heapUsed=160MB heapTotal=202MB rss=340MB。 - 16:51:33 ——
pid=53940 heapUsed=444MB heapTotal=509MB rss=618MB。 - 16:52:33 ——
pid=53940 heapUsed=957MB heapTotal=1030MB rss=1162MB。三分钟三倍,斜率外推下一分钟破 2GB。 - 16:53:22 —— 旧 daemon 最后一条正常业务日志(
[skills-fetch] response)。 - 16:53:38.273 —— 新进程首个标记:
[CodeCache] enabled {"processName":"daemon"}。 - 16:53:38.288 ——
[DaemonLog] session started {"pid":73936,"ppid":72748,...}。 - 16:53:39.584 —— 会话
a257d30f被状态同步器置为terminated。 - 16:53:54.262 —— 新 daemon 记下第一条:
ChildProcessCrash: Child process gone (cli): reason=exit:1, exitCode=1。
关键间距:16:53:22 到 16:53:38 之间有 16 秒空白 —— 旧进程没有留下任何 shutdown/exit/error 记录,属被直接终止。
三、证据与复现命令
1、内存暴涨
grep "DaemonMemWatch" <logs>/daemon.log | tail -30
2、守护失效(每 10 秒一次)
grep "guardian:sample" <logs>/daemon.log | tail -20
原文:[guardian:sample] batch pidusage failed: Error: spawn wmic ENOENT
频次:旧进程最后 46 行日志里出现 11 次,即持续失败、无一成功。
3、进程换代与父子关系
grep "DaemonLog] session started" <logs>/daemon.log
原文:[DaemonLog] session started {"pid":73936,"ppid":72748,"nodeVersion":"v22.21.1","electron":...}
4、崩溃报告(换代是常态的直接证据)
目录:<logs>/Crash-Log/
命名规则:crash-report-<进程名>-<pid>-<launchedAt 本地时刻>.json
(时间戳取报告内 launchedAt 字段,不是崩溃时刻)
现有 14 份,daemon 的跨 09-28 / 10-01×2 / 10-02×2 / 10-06×2 / 10-08 / 10-09 —— 至少 6 个日子发生过换代。另有 crash-report-main-* 5 份、crash-report-sidecar-* 1 份。
每份报告体例一致(示例为 10-09 那次),条目形如:
{
"timestamp": "2026-10-09T00:53:54.262+08:00",
"type": "child_process_crash",
"errorMessage": "Child process gone (cli): reason=exit:1, exitCode=1",
"childProcess": { "name": "cli", "exitCode": 1, "disposition": "unexpected_crash" }
}
.processed-crashes.json 里的数字是已处理条数(53940=12、73936=4),不是崩溃次数。
5、连带关系
53940 名下 12 条崩溃条目,时间点全部落在会话起止附近(其中 23:32:00 那条,正好等于一次执行会话排期的触发时刻)。
四、影响面
- 任何正在跑的会话都可能被换代打断,形态是"跑着跑着变 terminated",且来不及做收尾动作。
- 本次实际损失:一个四步目标的第 4 步执行会话在做完界面产物后 1 秒被终止,产物虽已落盘,但验证与上报全部丢失;更严重的是它持有的域锁无人释放,形成孤儿锁,导致后续 10 棒检查会话连续空转(01:29–05:59)。
- 崩溃报告中
cli exit:1是结果不是原因 —— 它是随 daemon 一起被带走的,排查时不要被这一行带偏。
五、建议
1、修 guardian 的采样方式 —— 把 wmic 依赖换掉(Windows 11 已弃用/移除 wmic,改用 PowerShell CIM 或 Node 原生接口)。这是本次事件中唯一明确、可修、且与现象直接相关的缺陷。
2、daemon 被杀前留痕 —— 现在从"最后一条业务日志"到"新进程启动"之间是 16 秒真空,外部无法判断是 OOM、被父进程杀、还是 native crash,建议补一条落盘的退出原因。
3、daemon 内存上限与自愈 —— 内存从 76MB 涨到 1GB+ 无任何预警;建议在阈值处先落日志、再重启,并且重启前给在跑的会话留收尾窗口(或至少在重启后主动标记受影响的会话,而不是让它们静默停在 terminated)。
六、未坐实项(如实标注)
daemon 内存为什么会涨到 1GB —— 日志只显示 Conversation event push summary {"received":1652542 → 1671269}(累计事件百万级),但这不足以断定是事件积压所致。要定这个因,需另做一次带堆快照的复现。本报告不对此下结论。