Files
TransPyC/work.md
T

145 lines
12 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.
# TransPyC 会话交接:A 阻塞已修复 + 阻塞 B 根因定位(GSList 泛型方法分派)
> 交接日期:2026-09-04。供下一会话直接续接。
## 1. 已修复并验证(TPC/llvmlite 源码已改,未 commit)
### 1.1 阻塞 A:链式成员访问静默吞 if → element_class 补登记(已双重验证)
- 现象:TPV 自举 SyntaxError 洪水;任何 name 实参 `foo(b)` 必失败。
- 根因:跨模块 import 类布局中 `rowptr[Token]` 自引用字段被 stub 退化为 i8*(HEAD 以来既有稳态,非本次引入);
HEAD 态 `Token | t.CPtr` 联合注解命中 import/class 字段收集的 BinOp 分支登记 element_class,char*→struct cast 可恢复;
rowptr 重构后登记链断 → `ps.cur.next.type == ...` 求值静默 None → `_HandleBoolOpLlvm` 放 unreachable 后 return None
→ `_HandleIfLlvm` 吞掉 if 主体(keyword 分支从未生成)→ 控制流损坏。
- 修复(TPC python 两处对称补丁):Subscript 字段收集分支增加 `rowptr[裸结构]`(Name/Attribute slice 在 Gen.structs 或 class_sha1_map)登记 element_class:
- `lib/core/Handles/HandlesImports.py` L1829-1850(import 类字段,如 Token.next)
- `lib/core/Handles/HandlesClassDef.py` L841-863(本地类字段,如 Parser.cur)
- 验证:全量重建(普通 122.75s)后 IR 中 `_parse_call` Name 分支三条件齐全(bitcast i8*→Token* + type==10 + op_subtype==11)、keyword 主体完整、无 unreachable;
`foo(b)`/`foo(b, k=5)`/`foo(b, 7)` 解析通过(SyntaxError 洪水消失)。
### 1.2 DeepCopy bad-free(ASan 定位,已修复)
- `includes/llvmlite/__types.vp` `_DeepCopyDepth` 的 `case _: stdlib.free(new_ty)` 对 MemBuddy(buddy) 分配的内存用 stdlib.free(只释放 malloc 块)→ 0xC0000374 / ASan bad-free。
- 修复:改 `pool.free(new_ty)`(buddy 回收)。修复后崩溃点前移到阻塞 B(dump_ir param 链)。
## 2. 阻塞 B 根因已定位(未修复,下一会话主攻)
现象:翻译首个 include(stdint.vp)完成后 `dump_ir → LLVMModule.PrintModule → param_get_ty` 空指针崩(param 指针=垃圾)。
定位过程(DUMPDBG 插桩 + ASan):
- `printf`(Translator 预注入 declare,`Translator.vp` L455-461)的 Params GSList 异常:`Count=0` 但 `Head` 非空、param 节点 `Next=1`、`func.Next` 也是非堆垃圾。
- 铁证(output/625716485a97ad4e.ll L801-803,llvmlite/__function.vp `function_add_param`):
`params.append(param)` 被编译为 `bitcast GSList* → LinkedNode*` + 调用 **`LinkedNode.append`**(linkedlist.vp 的兄弟类,双链树 48B)。
`function_add_block` 同样错误(L840-842)。
- 根因链(TPC python 泛型方法分派 bug):
1. `GSList[T].append` 泛型方法**从未生成/特化**(linkedlist 模块产物只有 LinkedNode.append;对照 list[T] 有特化方法);
2. `params: rowptr[GSList[Param]]` 局部变量 var_struct_class 未登记(初值 func.Params 为 i8*,未命中 HandlesAnnAssign L538-541)→ ClassName=None;
3. ObjVal 为 i8* → HandlesExprCall `_HandleMethodCallLlvm` L3055 **FakeDuck 分支**遍历所有类,选中第一个有 append 的类 = LinkedNode。
4. LinkedNode.append(字段 parent/child/last_child/prev/next/child_count,48B)打在 24B GSList(Head/Tail/Count)上 → **写穿 24B**(吻合 memhub DET 命中的 24B 块越界写,越界区为指针值)。
- 下一步建议:对照 `list[T]`(_list.vp)泛型方法特化注册机制,查 TPC 为何不给 GSList[T] 使用处生成 `GSList[Param].append` 特化;
候选入口:HandlesExprCall `_try_complete_generic_specialization`(L2523) / collect_class_methods(L2370) / 泛型类方法模板传播。
## 3. 环境状态
- 源码改动(未提交):HandlesImports.py、HandlesClassDef.py(1.1);includes/llvmlite/__types.vp(1.2)。
- `includes/llvmlite/__module.vp` 的 DUMPDBG 插桩**已清理**(内容与 HEAD 一致)。
- `TransPyV/output/TransPyV.exe` 当前是**带插桩残留的 ASan 版**(3,140,096 B),下次验证前需全量重建还原(普通 122s / ASan ~190s)。
- `Test/Sha1Test/App/main.vp` 已还原为原始 hashlib 用例;临时探针文件 `_v*.vp/_a_probe.vp` 已删;`TransPyV/temp/_sha1*.log`、`_sha1main.bak.vp` 可清理。
## 4. 调试方法备忘(重要,避免重复踩坑)
- TPC ASan 构建:`PATH` 前置 `D:\msys64\clang64\bin` 后 `python Projectrans.py --project ./TransPyV/project.json --clean --rebuild-includes --clear-cache --asan`(~190s)。
- TPV exe 的 stdout **重定向到文件会丢输出**(WriteConsole/句柄缓存),必须控制台直跑观测;但控制台模式下 abort 会吞未 flush 的 printf——诊断 printf 后必须 `stdio.fflush(None)`。
- 单文件 `--src` 模式翻译阶段缺类型上下文(int 等注解解析失败)是伪影,真实验证须跑工程(`--project TransPyV/Test/*/project.vpj --phase 1`)。
- 复现崩溃:`Sha1Test`(import hashlib 链)与 `TransPyV/Test/project.vpj`(全量)phase1 均可在 ~10s 内复现 0xC0000374/AV。
- 模块 sha1 → 源文件:`TransPyV/temp/_sha1_map.txt`(TPC 全量重建后刷新);运行期(TPV)模块 hash 由其自己内存表维护。
## 5. Commit 建议(conventional commits,中文,TransPyC 根仓库)
> `fix(core): rowptr[裸结构] 字段补登 class_member_element_class,修复链式成员访问静默吞 if(TPV 自举 SyntaxError 洪水根因)`
> `fix(llvmlite): _DeepCopyDepth 兜底分支改用 pool.free 释放 buddy 内存(原 stdlib.free 致堆损坏)`
阻塞 B 修复落定后再提交(含 GSList 分派修复)。
---
# 会话续接 2026-09-04(后半段):插桩清理 + 崩溃点前移复现(json/__init__.vp prescan alloca)
> 承接上文"阻塞 B"。本段未改 TPC/llvmlite 语义代码,完成取证与状态刷新。
## 6. 本段完成
1. **清理全部残留 `[DBG-TMP]` 插桩(4 个文件)**
- `TransPyV/App/lib/core/Gen/AssignGenMixin.vp`(prescan var_ty/alloca.Ty 打印)
- `TransPyV/App/lib/core/Gen/Expr/ExprGenName.vp`(nm alloca/Ty hex dump)
- `TransPyV/App/lib/core/Gen/Func/FuncGenDef.vp`(translate_function_def 打印)
- `TransPyV/App/lib/core/Gen/Type/TypeGenResolve.vp`(attr CUInt64T builtin/ctyp/found 打印)
2. **全量重建验证**:`python Projectrans.py --project ./TransPyV/project.json --clean --rebuild-includes --clear-cache --asan` 成功(~142s),
产物 `TransPyV/output/TransPyV.exe`(ASan),二进制扫描 `DBG-TMP count=0`。
## 7. 干净复现结果(重要,供续接)
命令:`.\TransPyV\output\TransPyV.exe --project ./TransPyV/project.vpj --clear-cache --rebuild-includes --asan --run --detection` → exit 1。
- Phase1 翻译到 `./includes/json/__init__.vp`([22/53])时崩溃,日志被 \r 进度覆盖/printf 中断截断,**必须控制台直跑看 ASan**。
- ASan 栈(确定性):`AssignGenMixin.translate_annassign_prescan → StmtGenDeclMixin.pre_scan_allocas → FuncGenDef.translate_function_def → Translator.translate_children`
→ `VarGenMixin._alloca_at_entry → build_alloca_at_entry(IRBuilder) → block_append_text → block_append_line` **READ access-violation @ 0x0308735d0002**。
- 模块 sha1(→源):`625716485a97ad4e`=includes/llvmlite/__function.vp、`fba457abe40d6872`=includes/llvmlite/__builder.vp、
`b9ef07833ceba511`=VarGenMixin、`b024541f0bd472bc`=AssignGenMixin、`ddb2be6edcee9cb9`=FuncGenDef(App)。
- 与历史崩溃点同族:`build_alloca_at_entry` 读 0xFFFFFFFFFFFF(旧)→ dump_ir ensure_opaque_for_type 读 -1(中)→ 现 block_append_line 读 0x0308735d0002(新)。均为"block/Lines 链表对象被写坏或读取越界指针"。
## 8. 结论与下一步方向
- 疑点收敛:json/__init__.vp 首个触发 AnnAssign 预扫描的函数(很可能是 `JsonValue.__new__` 的 `ptr: rowptr[JsonValue] = pool.alloc(...)`)
的 entry block/`Lines(GSList)` 已损坏(或跨模块 BasicBlock/Function stub 字段偏移读歪)。memhub/stdint 等前序 include 同路径成功 → 数据相关损坏而非全局性。
- 未决 todo(见前文):m2=定位 free list 重复 put 同一块写入者;m5=确认 LLVMType 对象创建即坏 vs allocator 污染。
- 方向建议:
1. 静态核对 `includes/llvmlite/__function.vp block_append_line`/GSList[T].append 是否仍错分派到 LinkedNode.append(上段"阻塞 B"理论——本段已证容器/append 大多数场景正常,需确认 json 路径是否被 48B 写穿 24B GSList);
2. 查 json/__init__.vp __new__ 翻译前是否有跨模块类型/结构体注册把 entry block 区域写坏;
3. 若需再插桩:改 includes 须 TPC 全量重建(~142s)生效(include 代码编译进 exe);插桩须 `stdio.fflush(None)`,且 stdout 重定向会丢进度(用 \r),ASan 报告须控制台直跑。
## 9. 教训备忘
- **Grep/ripgrep 工具会漏扫被 ignore 规则覆盖的目录**(本次 `Gen/Type/TypeGenResolve.vp` 残留 DBG 即因此漏检);
排查残留/全树关键字时用 python 全文件扫描(`os.walk` + 字节查找)兜底。
- exe 是否含插桩可用 `python -c` 二进制 find 快速验证(`DBG-TMP` count)。
---
# 会话续接 2026-09-04(第三段):MEMDBG 插桩完成(等全量重建验证)
## 10. 本段完成
1. **汇报复查**:TPC ASan 重建成功(exe 3,101,696B,插桩标记 count=0);TPV 干净复现仍崩
(1.log:READ AV @ 0x02ab4c870002,栈 = block_append_line → block_append_text →
IRBuilder.build_alloca_at_entry → VarGenMixin._alloca_at_entry → translate_annassign_prescan →
pre_scan_allocas → translate_function_def,与 §7 完全同族)。崩溃模块无法从重定向日志确认
(stdout 丢 flush,"memhub.vp" 只是最后一条 INFO)。
2. **静态核对排除 LinkedNode 误分派(重要)**:本次全新产物 output/*.ll 中
- `block_append_line`→`GSList[Line].append`(625716485a97ad4e.ll L1008)、
`function_add_param`→`GSList[Param].append`(L805)、`function_add_block`→`GSList[BasicBlock].append`(L843);
- 全 output 目录 **零实际 `call LinkedNode.append`**(仅 declare)。
→ 阻塞 B 旧理论(GSList.append 误分派 LinkedNode / 48B 写穿 24B)**已排除**;
崩溃是 block/Lines 对象**进入前**已被上游损坏(寄存器 rdx=0x4bec0f0002≈(block<<1)|2 野值)。
3. **MEMDBG 插桩(includes/memhub.vp,未提交,待 TPC 全量重建生效)**:
- `MEMBUDDY_DBG=1` 开关(L56-62)+ 4 处改动(注释里有清单):
① alloc 采样分支:新出块仍残留同 order free list → 报错退出(重复 put 实锤);
② free:归还前同 order free list 已含本块 → 报错退出(double-put);
③ free:无效/悬空 ptr(池内且 header 偶数=已释放)→ 报错退出(原静默吞);
④ 既有 [DET] 分配重叠 / _det_probe 下溢、越界写 **exit 前全部补 stdio.fflush(None)**
——此前这些 printf 因 stdout 重定向/abort 被吞,可能早已命中而 1.log 看不见。
- 均 `[MEMDBG]`/`[DET]` 前缀 + fflush,重定向到文件也能保留,可直接 `.\TransPyV\output\TransPyV.exe ... > 2.log` 后 grep。
4. **验证方法**:TPC 全量重建(--clean --rebuild-includes --clear-cache --asan,~142s)后跑
`.\TransPyV\output\TransPyV.exe --project ./TransPyV/project.vpj --clear-cache --rebuild-includes --asan --run --detection`,
观察是否出现 [MEMDBG] 重复归还 / alloc 重复出块 / 悬空 free / [DET] 重叠或越界写。
- 若三类 [MEMDBG] 都不触发而仍 AV:指向"stale 指针持活块"场景(free 合法但过早/
双 owner 复用)或跨模块字段偏移写歪——下一步看是否在 free 后立即对同块 alloc 做
"上一 owner 仍在用"追踪(检测模式已做 free 后 0xCD 填充,可观察崩溃值是否 0xCD 系)。
## 11. 环境状态
- 源码改动(未提交):HandlesImports.py、HandlesClassDef.py(§1.1);includes/llvmlite/__types.vp(§1.2);
**includes/memhub.vp(§10 MEMDBG 插桩)**。
- `TransPyV/output/TransPyV.exe`(ASan 3,101,696B)为**无 MEMDBG 插桩**的上一版,需全量重建后验证。