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:
TermiNexus committed 2026-10-02 02:18:55 +08:00
1 parent 1ad7abf33d
commit 01e95b51cf
3 files changed
+118 -1

No files matched your search

+24
View File
@@ -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