docs(memory): 记录基座工具执行的异常安全不变量与故障注入验证
This commit is contained in:
1 parent
48229c28b0
commit
bfacb020a8
1 file changed
+26
@@ -66,6 +66,25 @@ type: project
|
|||||||
流程:关 CAD → `cmake --build --preset R230 --config Debug` → 重启 `acad.exe`(`acad.rx` 自动加载)
|
流程:关 CAD → `cmake --build --preset R230 --config Debug` → 重启 `acad.exe`(`acad.rx` 自动加载)
|
||||||
→ 轮询 `127.0.0.1:8080` 监听。编译阶段可先行(语法错误会被提前暴露,只有链接会因占用失败)。
|
→ 轮询 `127.0.0.1:8080` 监听。编译阶段可先行(语法错误会被提前暴露,只有链接会因占用失败)。
|
||||||
|
|
||||||
|
## 基座健壮性:工具执行的异常安全(2026-10-14)
|
||||||
|
|
||||||
|
**不变量:`cad_mcp_frame` 的工具执行运行在 AutoCAD 主线程的窗口消息处理链上
|
||||||
|
(`TcpServerLoop` → `PostMessage` → `WndProc` → `ExecuteTaskInMainThread` → `mcp_Tools::Call`),
|
||||||
|
任何异常都不得逃逸出 `WndProc`,且异常路径上不得遗留文档写锁。**
|
||||||
|
|
||||||
|
**Why**:插件 `Execute` 在参数**类型**不符时会抛 `nlohmann::type_error`(如
|
||||||
|
`args.value("bulge", 0.5)` 收到字符串、`parsePoint` 对 `["a","b"]` 取 `get<double>()`——
|
||||||
|
它只查 `is_array()/size()>=2`,不查元素类型)。而 `dwg_review` 由 LLM 驱动、
|
||||||
|
**模型经常生成类型错误的参数** → 这是日常路径,不是"恶意客户端"场景。
|
||||||
|
原实现全程无 try/catch:异常逃逸出 `WndProc` 属未定义行为(表现为 CAD 崩溃),
|
||||||
|
且 `mcp_Tool_DllProxy::Execute` 的 `unlockDocument` 在异常路径被跳过 → 写锁泄漏。
|
||||||
|
|
||||||
|
**How to apply**:基座已统一兜住(`mcp_Tools::Call` try/catch → `-32603` → `result.isError=true`;
|
||||||
|
`HandleToolsCall` 校验 `params`/`arguments` 必须为对象、`name` 必须为字符串,否则 `-32602`;
|
||||||
|
`ExecuteTaskInMainThread` 兜底 try/catch + `!req.is_object()` → `-32600`;
|
||||||
|
DLL 代理写锁改为 `ScopedDocumentWriteLock` RAII)。**插件作者无需自行 try/catch**,
|
||||||
|
但仍不要在异常路径上留下副作用。新增/改动工具后跑 `verify_mcp_fault_injection.py` 回归。
|
||||||
|
|
||||||
## 验证结论(2026-10-13 实测通过)
|
## 验证结论(2026-10-13 实测通过)
|
||||||
|
|
||||||
- `verify_mcp_frame.py` 4/4 PASS(换行分帧 / >2KB 报文不截断 / string id 原样回显 / 通知不回包 / isError)。
|
- `verify_mcp_frame.py` 4/4 PASS(换行分帧 / >2KB 报文不截断 / string id 原样回显 / 通知不回包 / isError)。
|
||||||
@@ -74,3 +93,10 @@ type: project
|
|||||||
- **受控取证子循环实测生效**:LLM 自主调用了白名单内的 `get_drawing_info`/`get_layers`/
|
- **受控取证子循环实测生效**:LLM 自主调用了白名单内的 `get_drawing_info`/`get_layers`/
|
||||||
`find_zero_length`/`find_duplicate_entities`/`get_dimensions` 做二次确认。
|
`find_zero_length`/`find_duplicate_entities`/`get_dimensions` 做二次确认。
|
||||||
- 批注回写实测通过;注意 `add_leader_annotation` 的 `points` **必须 ≥2 个点**(首个为箭头)。
|
- 批注回写实测通过;注意 `add_leader_annotation` 的 `points` **必须 ≥2 个点**(首个为箭头)。
|
||||||
|
|
||||||
|
## 验证结论(2026-10-14 补充)
|
||||||
|
|
||||||
|
- `verify_mcp_fault_injection.py` **22/22 PASS**(畸形/类型错误请求:结构性错误回
|
||||||
|
`-32602/-32600/-32700`;工具内部类型异常被兜为 `result.isError=true`;反复注入 10 次后
|
||||||
|
CAD 存活、写锁未泄漏)。回归 `verify_mcp_frame` 4/4、`verify_stdio_bridge` 24/24、
|
||||||
|
`verify_annotate` 9/9、`dwg_review --check` 均正常。
|
||||||
Reference in new issue
Block a user