fix(gentype): register_ctypedef_from_source 先清表再注册,修 stdint.vp strcmp 悬空遍历崩溃
clear_ctypedefs 只在 translate 前调用,文件 reset_to(mark1) 回收后上一文件 CTypedefNames 表悬空(非 None);本函数去重遍历读已回收内存 → ASan strcmp 读地址 0x4(1.log)。开头 clear_ctypedefs 重建表,杜绝悬空遍历
This commit is contained in:
1 parent
55d4c4102a
commit
132c48d41a
1 file changed
+9
-21
@@ -130,11 +130,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
"""
|
||||
if annotation is None:
|
||||
return 0
|
||||
# 诊断(stdint.vp 崩溃定位):kind() 是 @t.CVTable 虚调用,若节点
|
||||
# vtable 指针错会直接 0xC0000005——打印确认虚调用是否正常。
|
||||
stdio.printf("[DIAG] ctypedef 检查: ann=%llu\n", t.CUInt64T(annotation))
|
||||
k_v: int = annotation.kind()
|
||||
stdio.printf("[DIAG] ctypedef 检查: kind=%d\n", k_v)
|
||||
if k_v != ast.ASTKind.Attribute:
|
||||
return 0
|
||||
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(annotation)
|
||||
@@ -142,18 +138,8 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
# TypeGenCType 直接访问 at.attr 可能按 stub 类型生成错误 GEP,
|
||||
# 读垃圾地址 → strcmp 0xC0000005 崩溃,stdint.vp 根因)。
|
||||
at_attr_v: str = ast.attribute_get_attr(at)
|
||||
# 诊断(stdint.vp strcmp 崩溃定位):手动逐字节检查 attr 前缀,
|
||||
# 避免 strcmp 读穿崩(attr 内容损坏/无 NUL 结尾)。prefix=1 表示
|
||||
# 内容正确('C''T''y''p'),则 strcmp 崩是读越界;=0 表示内容垃圾。
|
||||
attr_ok_d: int = 0
|
||||
if at_attr_v is not None:
|
||||
if at_attr_v[0] == 'C' and at_attr_v[1] == 'T' \
|
||||
and at_attr_v[2] == 'y' and at_attr_v[3] == 'p':
|
||||
attr_ok_d = 1
|
||||
if at_attr_v is None:
|
||||
return 0
|
||||
if attr_ok_d == 0:
|
||||
return 0
|
||||
# 限长比较替代 strcmp:attr 是零拷贝引用 src_buf 的 token 字符串,
|
||||
# 可能无 NUL 结尾("CTypedef" 后紧跟空格/其他字符),strcmp 会
|
||||
# 无限读穿到页边界 → 0xC0000005(stdint.vp 崩溃根因)。strncmp
|
||||
@@ -200,7 +186,6 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
return 0
|
||||
n: t.CSizeT = len(ch)
|
||||
count: int = 0
|
||||
stdio.printf("[DIAG] CTypedef 扫描: 开始 n=%zu\n", n)
|
||||
i: t.CSizeT
|
||||
for i in range(n):
|
||||
child: ast.AST | t.CPtr = ch.get(i)
|
||||
@@ -209,12 +194,8 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
if child.kind() != ast.ASTKind.AnnAssign:
|
||||
continue
|
||||
aa: ast.AnnAssign | t.CPtr = (ast.AnnAssign | t.CPtr)(child)
|
||||
# 诊断(stdint.vp 访问违规崩溃定位):打印 AnnAssign 节点与
|
||||
# annotation/target/value 字段地址——垃圾地址=stub 字段访问偏移错。
|
||||
stdio.printf("[DIAG] CTypedef 扫描: AnnAssign %d/%d aa=%llu ann=%llu tgt=%llu val=%llu\n",
|
||||
i, n,
|
||||
t.CUInt64T(aa), t.CUInt64T(aa.annotation),
|
||||
t.CUInt64T(aa.target), t.CUInt64T(aa.value))
|
||||
if aa.annotation is None:
|
||||
continue
|
||||
# 检测注解是否为 t.CTypedef
|
||||
if self._is_ctypedef_annotation(aa.annotation) == 0:
|
||||
continue
|
||||
@@ -246,6 +227,13 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
"""
|
||||
if pool is None or src is None:
|
||||
return 0
|
||||
# 文件边界防护:clear_ctypedefs 只在 translate 前调用(Phase1Main
|
||||
# L800),文件级 reset_to(mark1) 回收本文件翻译期 pool 分配后,上一
|
||||
# 文件的 CTypedefNames 表指针悬空(非 None,list 本身也 pool 分配)。
|
||||
# 本函数去重遍历(register_ctypedef 内 strcmp)读已回收内存 →
|
||||
# 0xC0000005(1.log: stdint.vp 翻译时 strcmp 读地址 0x4)。先清表
|
||||
# 重建,杜绝悬空遍历。翻译期 Handle 按需注册不受影响(L800 会再清)。
|
||||
self.clear_ctypedefs()
|
||||
src_len: t.CSizeT = string.strlen(src)
|
||||
count: int = 0
|
||||
line_start: t.CSizeT = 0
|
||||
|
||||
Reference in new issue
Block a user