递归火山软件开发平台
标题:
AI分析的火山关闭卡顿的问题
[打印本页]
作者:
msm1985
时间:
14 小时前
标题:
AI分析的火山关闭卡顿的问题
本帖最后由 msm1985 于 2026-10-20 00:45 编辑
# 火山开发平台关闭卡死诊断报告
## 1. 目标与版本
| 项 | 值 |
|---|---|
| 文件 | D:\Program Files\vol_dev\win_android_chs_person\bin\x64\voldev_awp.exe |
| 大小 | 3,743,744 字节 |
| 版本 | 1.0.0.26 |
| 描述 | 递归火山软件开发平台 |
| SHA256 | 381671eabe92f21e90b2e0a7947adac9cdb176ea3e7674efc0b209179796d099 |
| 编译 | VS2013 编译,C++ MFC 自绘界面(mfc120u.dll) |
## 2. 现象
- 点击关闭按钮后界面卡死,鼠标移动都不跟手(自绘窗口不响应)
- 视频播放不卡(独立进程硬解,不受影响)
- 进程长期残留,任务管理器显示内存占用不释放
## 3. 诊断方法
1. 静态反编译:REA / Ghidra 反汇编 voldev_awp.exe、mfc120u.dll
2. 运行时线程级监控:PowerShell 每 250ms 采样各线程 CPU 增量与状态(45 秒)
3. 复现 + 内存转储:启动实例 → PostMessage WM_CLOSE → MiniDumpWriteDump 抓取卡死态转储(voldev_hang2.dmp,1.2GB)
4. 窗口枚举:卡死期间枚举全部顶层窗口(含隐藏窗口)
## 4. 复现观测结果
| 时间点 | 状态 |
|---|---|
| 点击关闭后 1 秒内 | 所有可见窗口消失;主窗口(_VolDevMainFrame3)被 SW_HIDE 隐藏,
**未销毁**
,rect 尺寸正常 |
| 卡死期间窗口枚举 | 仅剩主窗口(隐藏)、ComboLBox 残留、GDI+ Hook、IME;
**无任何 #32770 对话框**
|
| 卡死期间主线程 | RIP=win32u.dll+0x17B4(GetMessage 等待),CPU 增量 0,MFC 模态消息循环(comctl32 → mfc120u) |
| 其余线程 | 全部阻塞于 ntdll/win32u/KERNELBASE 等待态 |
| 最终行为 | 测试实例约 20~60 秒后自行退出;期间完全假死 |
## 5. 根因机制
```
WM_CLOSE → 隐藏主窗口(SW_HIDE)
→ 进入 MFC 模态消息循环
→ 循环退出条件永远不满足(等待某后台线程/资源清理完成)
→ 主线程在 GetMessage 空转等待,CPU 0%
→ 窗口不可见、无对话框可交互,进程长时间残留
```
关键证据:
- 主线程栈候选:win32u!GetMessage ← comctl32 消息循环 ← mfc120u(MFC 模态循环)← voldev_awp.exe+0x1FFC50 / +0xA4070 ← 主框架析构链 FUN_1400c16f0(voldev+0xC16F0 → +0x204D80 → +0xC172D)
- FUN_1400c16f0 为主框架析构:DestroyMenu、Ordinal_9001(MFC 基类析构)、FUN_1400c9b20(工程/文档清理)、FreeLibrary
- FUN_1400a4070 析构子对象时调用对象 vtable+0xd0 虚接口(+0x4D0 字段)
- 无对话框窗口 → 排除"保存文档对话框等待用户点击"场景
- 与早期静态分析一致:退出流程含"等待对话框"机制(CWattingVolDevDialog 等待对话框)
## 6. 与用户场景的对照
- 空工程启动后直接关闭即可稳定复现 → 卡点不在文档保存,而在退出流程自身的模态循环
- 用户场景工程越大,退出路径上的清理/保存越重,等待时间更长,观感更严重
## 7. 缓解建议(按收益排序)
1. 退出前先关闭全部工程(文件 → 关闭工程),再退出 IDE,绕过工程关闭相关等待路径
2. 卡死后直接任务管理器结束进程(窗口已隐藏,已保存数据无丢失风险)
3. 配置调优:`doc.save_back_count=5` 已在用户配置中,可进一步调小降低保存负担
4. 等待官方修复;不推荐 patch 二进制(无签名、风险高)
## 8. 追查结论:模态循环在等什么(转储线程等待对象分析)
方法:抓取带句柄表的卡死转储(voldev_hang3.dmp,Normal|HandleData,3.1MB),解析全部 20 个线程的 RIP、寄存器与栈上句柄引用,对照 613 项进程句柄表。
| 线程类别 | 数量 | RIP 位置 | 等待对象 | 判定 |
|---|---|---|---|---|
| 主线程(TID 30836) | 1 | win32u.dll+0x17B4(NtUserGetMessage) | 线程消息队列 |
**模态循环空转等消息**
|
| Tp 线程池线程 | 8 | ntdll+0x162B84(NtWaitForWorkViaWorkerFactory) | TpWorkerFactory / IoCompletion | 空闲等待,正常 |
| IoCompletion 等待线程 | 2 | ntdll+0x15EFD4 | IoCompletion | 空闲等待,正常 |
| 无名 Event 等待线程 | 2 | ntdll+0x15EF34 | 无名 Event(无名字) | 应用线程空闲等待 |
| AlertByThreadId / Timer | 3 | ntdll+0x15FA04 / 0x15F534 | rcx=0x0~0x2 | 空闲等待,正常 |
| UI 消息等待线程 | 3 | win32u+0xAD74 | 窗口消息 | 空闲等待,正常 |
| 其它线程池 | 1 | ntdll+0x15EFD4 | IoCompletion | 空闲等待,正常 |
关键事实:
1.
**不存在死锁链**
:没有任何线程持有互斥/事件等另一个线程正在等待的同步对象;所有等待均为"单线程等待空闲资源",无互锁。
2.
**没有任何后台线程在执行退出清理任务**
:19 个非主线程全部是线程池/IO/UI 的空闲等待,CPU 不消耗、无任务队列活动。因此"等后台线程清理完成"的假设
**被排除**
。
3.
**主线程模态循环等的是窗口消息**
:GetMessage 在消息队列上等待,但退出循环所需的终止消息(WM_QUIT 或模态循环退出标志触发的消息)
**永远不会到来**
。
4. 主线程栈上引用的命名对象仅有系统基础设施(\KnownDlls 目录、SM0:33164:304:WilStaging 信号量、userenv.mutex.sogouime 搜狗输入法互斥体),均与退出流程无关。
最终根因判定:
```
WM_CLOSE → 主框架析构链 FUN_1400c16f0
→ 主窗口被 SW_HIDE 隐藏(未销毁)
→ 析构链进入 MFC 模态消息循环(mfc120u,comctl32 驱动)
→ 循环退出条件(WM_QUIT / 退出标志消息)从未被设置
→ 主线程在 GetMessage 永久空转
→ 进程假死约 20~60 秒后因其它机制(看门狗/超时)自行退出
```
即:不是"在等某个后台线程/资源",而是
**退出流程自身的代码缺陷**
——进入模态循环后缺少触发退出条件的路径(预期由隐藏窗口后的某后续步骤发出,但该步骤因窗口隐藏/流程短路而未执行),循环因此空转等待一条永远不会来的消息。
## 9. 结论与建议
- 卡死为 voldev_awp.exe 退出流程逻辑缺陷:主框架析构时隐藏窗口后进入 MFC 模态循环,循环终止条件永不满足。
- 与文档保存无关(空工程即可复现,且无保存对话框出现)。
- 缓解:退出前先关闭工程;卡死直接结束进程(数据已在日常编辑中落盘,无丢失风险)。
- 不建议 patch 二进制(无签名、风险高),建议反馈官方(版本 1.0.0.26)。
作者:
a759077146
时间:
24 分钟前
顶顶顶
作者:
blackvolcano
时间:
14 分钟前
隐藏窗口?假装很快,掩耳盗铃?
欢迎光临 递归火山软件开发平台 (http://bbs.voldp.com/)
Powered by Discuz! X3.4