55 lines
4.2 KiB
Markdown
55 lines
4.2 KiB
Markdown
# Fix-BUG-20261006-0003
|
||
|
||
> 适用场景:记录某个 BUG 的修复方案、影响评估、验证结果与落地信息。
|
||
|
||
## 关联信息
|
||
|
||
- Fix ID: Fix-BUG-20261006-0003
|
||
- 关联 BUG ID: BUG-20261006-0003
|
||
- 修复目标: 消除 0B 固定 IME 定位路径的 WndProc 重入自锁,同时保持日志严格序号和可审计关联
|
||
- 状态:验证通过(微软拼音 Forward/Consume 与搜狗运行时 fail-open)
|
||
- 负责人: Codex
|
||
- 分支 / 版本: `master`,未提交工作区
|
||
|
||
## 修复方案
|
||
|
||
- 将定位路径拆成三个阶段:
|
||
|
||
1. 锁内解析并写入原始 `wndproc_enter`,更新 IME/规则状态,复制不可变的定位请求。
|
||
2. 锁外调用 `ImmGetContext`、`ImmSetCompositionWindow`、`ImmSetCandidateWindow` 和 `ImmReleaseContext`。
|
||
3. 再次加锁校验探测仍启用、HWND 与 `hwndInstanceId` 未变化,更新 `imePositionReady` 和成功计数,并写入独立 `ime_position` 结果记录。
|
||
|
||
- `ime_position.parentSequence` 指向触发它的 `wndproc_enter.sequence`;结果记录只在 IMM32 调用返回后分配序号。这样 setter 同步重入产生的消息自然位于父 enter 与结果记录之间,不会因“预留低序号、事后补写”破坏 `sequenceStrict`。
|
||
- 使用 WndProc 线程局部的 `imePositionApiCallActive` 抑制定位 API 调用期间的递归定位;重入消息仍正常采集、转发和记录,只是不再次调用定位 setter。
|
||
- 分析器同时兼容旧版挂在 `wndproc_enter` 上的位置结果与新的 `ime_position` 记录,并校验新记录的 `parentSequence` 存在且严格早于结果记录。
|
||
|
||
## 影响评估
|
||
|
||
- 正确性: 移除持锁 IMM32 setter,避免 SRW 自锁;独立结果记录保留调用结果、坐标、触发消息与父序号。
|
||
- 并发: `ProbeState::lock` 只保护状态快照与结果提交,不跨越任何定位 setter;完成阶段会拒绝已经 detach 或 HWND 实例变化的过期结果。
|
||
- 顺序: 父 enter 先入缓冲,重入消息随后入缓冲,最终结果记录最后入缓冲;全局序号与实际可观察顺序一致。
|
||
- 行为边界: 仅影响 `STELLARX_ENABLE_INPUT_PROBE` 且显式开启 0B 人工定位的诊断路径;默认生产构建、公共 API 与正常消息返回策略不变。
|
||
- 风险: 不同 IME 仍可能自行调整候选 UI;setter 成功只证明调用链成立,最终位置仍需人工视觉确认。
|
||
|
||
## 验证结果
|
||
|
||
- 已完成:
|
||
- Debug x64 探测构建完成编译与链接;仅有 EasyX 头文件既有 C4201 警告。
|
||
- 旧失败日志重放仍为 268 条严格递增记录、零丢失,并明确判为缺少关闭收口的无效实验。
|
||
- 默认 Debug x64 单元测试 15/15 通过。
|
||
- Windows PowerShell 5.1 与 PowerShell 7.6.5 对三份 0B 脚本均为 0 个 AST 解析错误。
|
||
- `git diff --check` 通过,仅输出仓库换行规范提示。
|
||
- 微软拼音 Forward 人工复验通过:窗口保持响应,组合串/候选 UI 位于固定锚点;结构日志为 1142 条严格递增记录、零丢失、规则唯一命中并 Forward、18/18 次定位成功、0 个孤立定位结果、关闭收口完整。
|
||
- 有效运行: `TestResults/InputProbe/0B/20261006-234544-007-603391f8-3a14-4c90-ab41-4d891ceb8f46/forward`。
|
||
- 人工截图: `manual-evidence/microsoft-pinyin-forward-composition-position-pass.png`,SHA-256 `1447E9F1AAD2C90A787AADC2594C78AE596336FC6D569EA1A22C69B2FCA5C3D5`。
|
||
- 微软拼音 Consume 同样保持响应,7/7 次定位成功且 Escape 唯一命中并被消费;有效运行位于 `TestResults/InputProbe/0B/20261007-000152-550-4c83bcda-12e8-4f4e-b616-1d1fe1f56a27/consume`。
|
||
- 搜狗 Forward 运行保持响应、定位 6/6;最终 Consume 请求因 Composition 条件不可证明而正确 fail-open,运行仍保持响应、定位 3/3、无孤立结果、零丢失并完整关闭。最终有效目录为 `TestResults/InputProbe/0B/20261007-033454-763-56a2630b-bf2a-4431-b501-38f6ff977dfe/consume`。
|
||
- 2026-10-07 默认 Debug x64 单元测试 15/15、UI fixture 1 轮和当前分析器回放通过。
|
||
|
||
## 落地信息
|
||
|
||
- Commit: 待验证与用户确认后提交
|
||
- PR:无
|
||
- 发布版本:未发布
|
||
- 备注: 本修复不进入阶段 1,不实现 FocusManager、生产 InputCollector 或键盘路由。
|