fix(gen): 修 vpi 生成阶段 is_file_func 读到已回收池的悬垂表(ASan 野读崩溃)
现场:TransPyV.exe(ASan)编译 EscapeOkTest 崩在 Phase A-pre-vpi → _GeneratePyiFromAst → _PyiFunction → compute_escape_summary → _ScanEscapes → _PushInductionEntry → is_file_func → HashTable._slot_hash (access-violation on unknown address 0xffffffffffffffff)。 根因(潜伏已久,非本阶段语义改动引起): - FileClassNames / FileFuncNames / FileVarNames / FileModuleSha1 是按文件重建的表, 表与键共用该文件的瞬时池;契约要求跨文件/跨阶段先清空再重建 (原写在 reset_visible_structs 里那四行)。 - Phase A-pre-vpi 为生成 vpi 会重新 lex/parse 每个文件,但不走 register_file_*、 也不清表 → _PushInductionEntry 的 is_file_func 只认 range 的判据,落在 Phase1 最后一个文件的表上,而那个池已被 reset_to(mark1) 回收。非 ASan 下常表现为读到 0/旧值 的静默错答,ASan 下 0xfd 填充 → 垃圾容量/垃圾 __slots__ → 野读崩溃。 修法: - 抽出 reset_file_name_window() 作为文件级名字窗口的唯一开启入口(原四行清空搬进去, reset_visible_structs 改为调它),并在注释里写死契约。 - 新增轻量 register_file_func_names(pool, tree):只重建本文件顶层函数名(核对过 vpi 路径只需这一张;FileClassNames/FileModuleSha1/FileVarNames 的读取点全在翻译期)。 - Phase A-pre-vpi 循环里,在 _GeneratePyiFromAst 之前调用 reset_file_name_window() + register_file_func_names(mb, tree_vp2)。 - register_file_classes / register_file_funcs 改为无条件重建(原来 没有才建 的写法在 表已被别的阶段建过时会静默复用悬垂表)。
This commit is contained in:
1 parent
79d1c86982
commit
41674d125c
3 files changed
+79
-8
No files matched your search
@@ -679,6 +679,12 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
|
||||
continue
|
||||
pyi_buf_vp2: bytes = stdlib.malloc(PYI_BUF_SIZE_P2)
|
||||
if pyi_buf_vp2 is not None:
|
||||
# 文件级名字窗口:本阶段为生成 vpi 重新解析出 tree_vp2,但**不走** register_file_funcs;
|
||||
# 而 _PyiFunction → compute_escape_summary → _ScanEscapes → _PushInductionEntry 会问
|
||||
# is_file_func("range")。不清窗口就会读到"上一个文件的表 + 已被 reset 的池"→
|
||||
# 悬垂指针(ASan access-violation / 非 ASan 静默错答)。见 StructGenMixin.reset_file_name_window。
|
||||
GenApi.reset_file_name_window()
|
||||
GenApi.register_file_func_names(mb, tree_vp2)
|
||||
pyi_pos_vp2: sizet = StubConverter._GeneratePyiFromAst(mb, tree_vp2, ent_vp2.Path, pyi_buf_vp2, PYI_BUF_SIZE_P2)
|
||||
if pyi_pos_vp2 > 0:
|
||||
pyi_path_vp2: str = StubMergerCollect._sliced_path(temp_dir, td_len_vpa, ent_vp2.Sha1, "vpi")
|
||||
|
||||
Reference in new issue
Block a user