debug(gen): 一次性取证插桩——Generator 结构体登记/查找全链路(用完删除)
覆盖点(全部以 [DBG-GEN] 为前缀,仅打印不改行为): - StructGenMixin.register_struct:IN(name/sha1/ty/StructCount)、DEDUP(命中条目) - StructGenMixin.add_field:逐字段打印写入 Generator 条目的字段名与下标 - StructGenMixin.find_struct_by_module:IN / HIT / MISS - StructGenMixin.lookup_field(field=FuncGenBase):struct_ty 名、按 Ty 指针命中条目的 全字段名、以及结构体表内所有含 "Generator" 的条目 - VpiReader._inject_class_struct_declare:IN / EXISTING / RENUM-SKIP / EMPTY / FIELD-FAIL / REGISTERED - ClassGenDef.translate_class_def:EXISTING / REGISTER / DONE 目的:一次重建即可判定 Generator.FuncGenBase 查不到是"命中空/旧条目""Ty 错配" 还是"字段名悬空",并看清是哪条登记路径产出的条目。
This commit is contained in:
1 parent
1ad7abf33d
commit
01e95b51cf
3 files changed
+118
-1
No files matched your search
@@ -2780,6 +2780,14 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
|
||||
flat_buf_c[p_len] = '_'
|
||||
string.strcpy(flat_buf_c + p_len + 1, cls_name)
|
||||
real_name = flat_buf_c
|
||||
# [DBG-GEN] 一次性取证(用完删除)
|
||||
_dg_v_isgen: int = 0
|
||||
if string.strcmp(real_name, "Generator") == 0:
|
||||
_dg_v_isgen = 1
|
||||
_dg_v_s: str = "<null>"
|
||||
if src_sha1 is not None:
|
||||
_dg_v_s = src_sha1
|
||||
stdio.printf("[DBG-GEN] vpi inject_class IN name=Generator src_sha1=%s\n", _dg_v_s)
|
||||
# REPL(ReplStubLayoutMode,见文件末"REPL:includes 类完整布局与虚表恢复"):
|
||||
# 本类若已由 .stub.ll 驱动的路径接管 ⇒ 这里整类让位——已登记(或本遍就地
|
||||
# 登记成功)只标可见;父类未就绪 ⇒ 本遍不登记(收尾遍补齐);布局不可信 ⇒
|
||||
@@ -2799,6 +2807,9 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
|
||||
existing_c: GenTypes.StructEntry* = GenApi.find_struct_by_module(real_name, src_sha1)
|
||||
if existing_c is not None and existing_c.Ty is not None:
|
||||
GenApi.add_visible_struct(pool, real_name)
|
||||
if _dg_v_isgen != 0:
|
||||
stdio.printf("[DBG-GEN] vpi inject_class EXISTING name=Generator fcount=%d\n",
|
||||
existing_c.FieldCount)
|
||||
return 1
|
||||
# REnum 类(class X(t.REnum))跳过:布局 {i32 __tag, <payload>} 由
|
||||
# ClassGenEnum._translate_renum_def 按变体计算;vpi 侧按普通 struct 注册
|
||||
@@ -2806,6 +2817,8 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
|
||||
# 留给源模块正式翻译注册。LLVMType 本就因 field_count==0 早退,此守卫把
|
||||
# 该行为显式化,避免将来 REnum 带直接字段时被误注册为普通 struct。
|
||||
if _vpi_class_is_renum(class_cd) != 0:
|
||||
if _dg_v_isgen != 0:
|
||||
stdio.printf("[DBG-GEN] vpi inject_class RENUM-SKIP name=Generator\n")
|
||||
return 0
|
||||
# 规则 5.5 的证据前置(**必须早于**下方字段注解解析):
|
||||
# 本函数在**注入期**解析字段注解(GenApi.resolve_annotation_type →
|
||||
@@ -2862,6 +2875,12 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
|
||||
pool, m_aa_c.annotation, imported_modules, from_imports, trans, 0)
|
||||
if field_ty_c is None:
|
||||
# 字段类型解析失败:不注册该类(留给源模块编译注册),不 fatal
|
||||
if _dg_v_isgen != 0:
|
||||
_dg_v_fn: str = "<null>"
|
||||
if m_tgt_c.id is not None:
|
||||
_dg_v_fn = m_tgt_c.id
|
||||
stdio.printf("[DBG-GEN] vpi inject_class FIELD-FAIL name=Generator field=%s\n",
|
||||
_dg_v_fn)
|
||||
return 0
|
||||
if field_count < GenTypes.FIELD_MAX:
|
||||
field_names_buf[field_count] = sizet(m_tgt_c.id)
|
||||
@@ -2870,6 +2889,8 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
|
||||
# 3. vpi 存根不含类字段(只序列化 class 名 + def 签名)→ field_count 恒为 0;注册空类会让源模块编译时 find_struct_by_module 命中空类
|
||||
# → "结构体已注册但字段数为0" InternalCompilerError。故改为不注册:依赖模块已编译时命中真实类(上方已处理),未编译时由 _deps_pending 多遍收敛。
|
||||
if field_count == 0:
|
||||
if _dg_v_isgen != 0:
|
||||
stdio.printf("[DBG-GEN] vpi inject_class EMPTY name=Generator\n")
|
||||
return 0
|
||||
# 4. 构建 ParamNode 链表
|
||||
first_node_c: rawptr[llvmlite.ParamNode] = None
|
||||
@@ -2941,6 +2962,9 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
|
||||
af_ty_c: llvmlite.LLVMType* = (llvmlite.LLVMType*)(field_types_buf[afi_c])
|
||||
GenApi.add_field(pool, entry_c, af_name_c, af_ty_c)
|
||||
GenApi.add_visible_struct(pool, real_name)
|
||||
if _dg_v_isgen != 0:
|
||||
stdio.printf("[DBG-GEN] vpi inject_class REGISTERED name=Generator fcount=%d ty=%s\n",
|
||||
field_count, type_name_c)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
@@ -94,6 +94,16 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
|
||||
# 检查是否已注册(用 SHA1 区分跨模块同名类)
|
||||
existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1)
|
||||
# [DBG-GEN] 一次性取证(用完删除)
|
||||
_dg_cd_isgen: int = 0
|
||||
if class_name is not None and string.strcmp(class_name, "Generator") == 0:
|
||||
_dg_cd_isgen = 1
|
||||
if existing is not None:
|
||||
stdio.printf("[DBG-GEN] classdef Generator EXISTING fcount=%d declare_only=%d\n",
|
||||
existing.FieldCount, trans._declare_only)
|
||||
else:
|
||||
stdio.printf("[DBG-GEN] classdef Generator EXISTING none declare_only=%d\n",
|
||||
trans._declare_only)
|
||||
# 空类注册不完整检测:existing FieldCount==0 但源类体声明了字段(vpi 注入/注册缺陷)。
|
||||
# 标记 _deps_pending 延迟会让空 entry 持久存在、多遍死锁不收敛 ⇒ 改为中和旧 entry
|
||||
# (置空 Name + Ty=None,使 find_struct_by_module 不再命中),走下方完整注册路径重建。
|
||||
@@ -571,6 +581,9 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
if entry is None:
|
||||
VLogger.error(f"failed to register {class_name}", "CLASS")
|
||||
return 0
|
||||
if _dg_cd_isgen != 0:
|
||||
stdio.printf("[DBG-GEN] classdef Generator REGISTER field_count=%d declare_only=%d\n",
|
||||
field_count, trans._declare_only)
|
||||
|
||||
# B5:记录 packed 标记到 StructEntry(供 __sizeof__/字段布局等派生查询)
|
||||
if is_packed_cd != 0:
|
||||
@@ -649,6 +662,9 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
if fe_c is not None:
|
||||
fe_c.IsConst = 1
|
||||
|
||||
if _dg_cd_isgen != 0:
|
||||
stdio.printf("[DBG-GEN] classdef Generator DONE fcount=%d\n", entry.FieldCount)
|
||||
|
||||
# Phase 1a 声明模式:只注册 struct + 设置 OOP 标志,不翻译方法体
|
||||
if trans._declare_only == 1:
|
||||
self.Gen.ClassGenVTable._translate_oop_methods(trans, cd, struct_ty, class_name, 1)
|
||||
|
||||
@@ -594,12 +594,35 @@ novirtual class StructGenMixin:
|
||||
sha1 参数在注册时直接设置 ModuleSha1(避免 set_struct_sha1 找错 entry)。
|
||||
"""
|
||||
if self.init_struct_table(pool) == 0: return None
|
||||
# [DBG-GEN] 一次性取证(用完删除)
|
||||
_dg_isgen: int = 0
|
||||
if name is not None and string.strcmp(name, "Generator") == 0:
|
||||
_dg_isgen = 1
|
||||
_dg_sh0: str = "<null>"
|
||||
if sha1 is not None:
|
||||
_dg_sh0 = sha1
|
||||
_dg_tn0: str = "<null>"
|
||||
_dg_g0: str = llvmlite.get_struct_name(struct_ty)
|
||||
if _dg_g0 is not None:
|
||||
_dg_tn0 = _dg_g0
|
||||
stdio.printf("[DBG-GEN] register_struct IN name=Generator sha1=%s ty=%s count_before=%d\n",
|
||||
_dg_sh0, _dg_tn0, self.StructCount)
|
||||
# 用类型指针去重(同一类型不重复注册,支持跨模块同名类)
|
||||
# 用 uint64 指针值比较(is 比较会触发类型安全检查解引用悬空 Ty)
|
||||
# 走 find_struct_by_type(其 Ty 索引判定已整体停用、恢复原线性扫描),
|
||||
# 去重语义 = 原去重扫描"首个 Ty 指针相等条目"(首注册优先),逐字节一致。
|
||||
existing: GenTypes.StructEntry* = self.find_struct_by_type(struct_ty)
|
||||
if existing is not None: return existing
|
||||
if existing is not None:
|
||||
if _dg_isgen != 0:
|
||||
_dg_en: str = "<null>"
|
||||
if existing.Name is not None:
|
||||
_dg_en = existing.Name
|
||||
_dg_es: str = "<null>"
|
||||
if existing.ModuleSha1 is not None:
|
||||
_dg_es = existing.ModuleSha1
|
||||
stdio.printf("[DBG-GEN] register_struct DEDUP name=Generator -> existing name=%s sha1=%s fcount=%d\n",
|
||||
_dg_en, _dg_es, existing.FieldCount)
|
||||
return existing
|
||||
if self.StructCount >= STRUCT_MAX:
|
||||
VLogger.error(f"table full, cannot register {name}", "STRUCT")
|
||||
return None
|
||||
@@ -748,6 +771,10 @@ novirtual class StructGenMixin:
|
||||
if struct_entry.FieldCount >= FIELD_MAX:
|
||||
VLogger.error(f"field table full for {struct_entry.Name}", "STRUCT")
|
||||
return -1
|
||||
# [DBG-GEN] 一次性取证(用完删除)
|
||||
if struct_entry.Name is not None and string.strcmp(struct_entry.Name, "Generator") == 0:
|
||||
stdio.printf("[DBG-GEN] add_field Generator[%d] name=%s\n",
|
||||
struct_entry.FieldCount, field_name)
|
||||
idx: int = struct_entry.FieldCount
|
||||
fe: GenTypes.FieldEntry* = self._get_field_entry(struct_entry, idx)
|
||||
if fe is None: return -1
|
||||
@@ -1118,6 +1145,14 @@ novirtual class StructGenMixin:
|
||||
if self.StructCount < 0 or self.StructCount > 200000:
|
||||
VLogger.error(f"StructCount 异常: {self.StructCount} (find_struct_by_module)", "STRUCT")
|
||||
stdlib.exit(1)
|
||||
# [DBG-GEN] 一次性取证(用完删除)
|
||||
_dg_fbm_isgen: int = 0
|
||||
if string.strcmp(name, "Generator") == 0:
|
||||
_dg_fbm_isgen = 1
|
||||
_dg_fbm_s: str = "<null>"
|
||||
if sha1 is not None:
|
||||
_dg_fbm_s = sha1
|
||||
stdio.printf("[DBG-GEN] find_struct_by_module IN name=Generator sha1=%s\n", _dg_fbm_s)
|
||||
if sha1 is not None:
|
||||
# 名索引快速路径:同名条目都位于 >= 首个同名下标处,故可从该下标起扫描
|
||||
# name+sha1(等价原全表扫描"首个 name 且 sha1 命中")。
|
||||
@@ -1134,9 +1169,14 @@ novirtual class StructGenMixin:
|
||||
if entry.ModuleSha1 is not None:
|
||||
# 同上:sha1 判等蕴含首字符相等,先比首字符再 strcmp。
|
||||
if entry.ModuleSha1[0] == sha1[0] and string.strcmp(entry.ModuleSha1, sha1) == 0:
|
||||
if _dg_fbm_isgen != 0:
|
||||
stdio.printf("[DBG-GEN] find_struct_by_module HIT name=Generator sha1=%s fcount=%d\n",
|
||||
entry.ModuleSha1, entry.FieldCount)
|
||||
return entry
|
||||
# SHA1 查找失败:不回退到 find_struct(会返回跨模块同名错误 entry)
|
||||
# 返回 None 让调用方创建新类型,避免 Phase B 用错误类型短路
|
||||
if _dg_fbm_isgen != 0:
|
||||
stdio.printf("[DBG-GEN] find_struct_by_module MISS name=Generator\n")
|
||||
return None
|
||||
# 无 SHA1:按类名查找第一个
|
||||
return self.find_struct(name)
|
||||
@@ -1304,6 +1344,43 @@ novirtual class StructGenMixin:
|
||||
if struct_ty is None or field_name is None or self.StructTable is None:
|
||||
return None
|
||||
|
||||
# [DBG-GEN] 一次性取证(用完删除)
|
||||
if string.strcmp(field_name, "FuncGenBase") == 0:
|
||||
_dg_ty: str = self._extract_struct_name(struct_ty)
|
||||
_dg_ty_t: str = "<non-struct>"
|
||||
if _dg_ty is not None:
|
||||
_dg_ty_t = _dg_ty
|
||||
stdio.printf("[DBG-GEN] lookup_field 'FuncGenBase' struct_ty=%s\n", _dg_ty_t)
|
||||
_dg_pm: GenTypes.StructEntry* = self.find_struct_by_type(struct_ty)
|
||||
if _dg_pm is not None:
|
||||
_dg_pn: str = "<null>"
|
||||
if _dg_pm.Name is not None:
|
||||
_dg_pn = _dg_pm.Name
|
||||
_dg_ps: str = "<null>"
|
||||
if _dg_pm.ModuleSha1 is not None:
|
||||
_dg_ps = _dg_pm.ModuleSha1
|
||||
stdio.printf("[DBG-GEN] ptr-match name=%s sha1=%s fcount=%d\n",
|
||||
_dg_pn, _dg_ps, _dg_pm.FieldCount)
|
||||
_dg_fi: int = 0
|
||||
while _dg_fi < _dg_pm.FieldCount:
|
||||
_dg_fe: GenTypes.FieldEntry* = self._get_field_entry(_dg_pm, _dg_fi)
|
||||
if _dg_fe is not None and _dg_fe.Name is not None:
|
||||
stdio.printf("[DBG-GEN] field[%d]=%s\n", _dg_fi, _dg_fe.Name)
|
||||
_dg_fi += 1
|
||||
else:
|
||||
stdio.printf("[DBG-GEN] ptr-match NONE\n")
|
||||
_dg_i: int = 0
|
||||
while _dg_i < self.StructCount:
|
||||
_dg_e: GenTypes.StructEntry* = self._get_struct_entry(_dg_i)
|
||||
if _dg_e is not None and _dg_e.Name is not None:
|
||||
if string.strstr(_dg_e.Name, "Generator") is not None:
|
||||
_dg_sh: str = "<null>"
|
||||
if _dg_e.ModuleSha1 is not None:
|
||||
_dg_sh = _dg_e.ModuleSha1
|
||||
stdio.printf("[DBG-GEN] tbl[%d] name=%s fcount=%d sha1=%s\n",
|
||||
_dg_i, _dg_e.Name, _dg_e.FieldCount, _dg_sh)
|
||||
_dg_i += 1
|
||||
|
||||
# ============================================================
|
||||
# 两遍查找策略(跨模块同名类冲突的根本修复):
|
||||
#
|
||||
|
||||
Reference in new issue
Block a user