Files
StellarX-kaifa/开发记录/Fix/Fix-BUG-20261006-0003-IMM32定位拆锁与重入保护修复.md
T
2026-10-07 04:09:36 +08:00

55 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 或键盘路由。