3.5 KiB
3.5 KiB
BUG-20261004-0001
适用场景:记录问题本身,不展开完整修复方案。修复内容写入对应的 Fix 文档。
基本信息
- ID: BUG-20261004-0001
- 标题: EasyX 原生窗口销毁后宿主事件循环未退出
- 状态:已修复
- 严重性:S2
- 优先级:P1
- 模块: Window / Dialog / EasyX 事件循环 / 输入探测
- 版本 / 分支:
master,生产修复基线c0eca1d - 环境: Windows / EasyX / Visual Studio 2022 / Debug x64
- 发现人: 用户与 Codex 协作探测
- 关联 Fix ID: Fix-BUG-20261004-0001
问题描述
- 现象: 真实微软拼音探测完成后关闭 EasyX 窗口,窗口从桌面消失,但
StellarX.UiFixture.exe和调用它的人工探测脚本继续运行,脚本无法进入隐私安全摘要阶段。 - 影响范围:
Window::runEventLoop()及Dialog::Show()自建轮询循环;当 EasyX 内部窗口线程完成原生 HWND 销毁,而宿主peekmessage线程没有收到对应WM_CLOSE时均可能挂住。 - 期望结果: 原生窗口生命周期结束后,普通事件循环和模态事件循环都应在安全点自行退出,探测脚本继续分析已落盘日志。
- 实际结果: 事件循环仅以宿主侧
WM_CLOSE为退出条件;窗口已经销毁时仍继续轮询。
复现信息
- 前置条件: 构建开启
StellarXInputProbe的StellarX.UiFixture,通过scripts/run-input-probe-manual.ps1 -ImeName MicrosoftPinyin启动。 - 复现步骤:
- 按人工清单完成微软拼音提交、重复字符、取消、候选选择和中英文切换操作。
- 关闭 EasyX 原生窗口。
- 观察窗口消失后脚本仍未输出摘要,fixture 进程仍存在。
- 复现概率:修复前真实人工会话稳定复现
- 最小复现 Demo:
StellarX.UiFixture.exe input-probe <result-dir>;普通循环和真实MessageBox::showModal()均可构造关闭回归。 - 证据:
- 会话目录:
TestResults/InputProbe/manual-20261004-194521-908-MicrosoftPinyin。 - 日志观察到
WM_CLOSE -> WM_DESTROY -> WM_NCDESTROY,但宿主 EasyX 消息批次没有取得WM_CLOSE。 - 关闭后原挂起进程 PID 32948 仍存在,结束该进程后脚本才能退出。
- 会话目录:
初步分析
- 疑似位置:
Window::runEventLoop()、Dialog::Show()与Window::WndProcThunk()之间的原生窗口生命周期同步。 - 触发条件: EasyX 的 HWND/WndProc 所在线程与调用
peekmessage的宿主线程不同,且原生关闭消息没有映射为宿主侧EX_WINDOW/WM_CLOSE。 - 相关线索:
- 独立
EasyX.ThreadProbe已确认双线程是 EasyX 固有模型,不是 UiFixture 夹具造成。 - 旧事件循环只在
peekmessage返回的消息为WM_CLOSE时停止。 - HWND 已失效后继续尺寸轮询或绘制还会扩大为失效句柄访问风险。
- 独立
- 最近相关改动: 阶段 0A 探测器首次把 WndProc 与宿主批次放进同一时间线,暴露了此前被单线程假设遮蔽的生命周期缺口。
跟踪信息
- 首次发现时间: 2026-10-04
- 最后更新时间: 2026-10-05
- 修复版本:
c0eca1d(fix: 原生窗口销毁后宿主事件循环未退出) - 验证版本: Debug x64;单元测试 15/15;普通与模态原生关闭自动回归通过
- 备注: EasyX
EX_SHOWCONSOLEfixture 由Start-Process托管时,原生关闭可能返回0xC000013A;该状态与“窗口关闭后进程仍挂住”是不同问题,回归以有界时间内自行退出为核心断言。阶段 0A 诊断实现与线程归属复现见c218c25。