fix(phase1): 加 translate 后存活块检查 + printf Params 链创建即校验 + dump 函数清单诊断
builtins.vp dump 卡死已定位:printf.fmt Param 的 Next 被越界写破坏成环 (Params.Count=1 但遍历超限)。本次加运行时证据收集: 1. printf declare 创建后立即打印 fmt Param 地址/Next(区分创建即坏 vs 后续被破坏) 2. dump_ir(OUTPUT_STUB) 打印模块函数清单+param0/next(确认创建上下文) 3. translate 返回后、dump 前 mb.check_alive_blocks(mark1)(抓 translate 期间写穿破坏的块 header/canary,rc=6 定位越界写穿文件)
This commit is contained in:
1 parent
43470b6e4a
commit
0cb0a12810
2 files changed
+41
No files matched your search
@@ -352,6 +352,14 @@ class Translator:
|
||||
return 1
|
||||
llvmlite.add_param(pool, printf_func, i8_ptr_ty, "fmt")
|
||||
printf_func.IsVarArg = 1
|
||||
# 诊断(builtins.vp dump 卡死根因排查):printf.fmt Param 创建后立即
|
||||
# 校验其 Next——区分"创建即损坏"(create_declare/add_param 环节问题)
|
||||
# 与"后续被越界写破坏"(dump 时遍历成环)。next=0 为正常。
|
||||
dbg_p0: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(printf_func)
|
||||
if dbg_p0 is not None:
|
||||
dbg_p0n: llvmlite.Param | t.CPtr = llvmlite.param_get_next(dbg_p0)
|
||||
stdio.printf("[DIAG] printf.fmt 创建后: param=%llu next=%llu\n",
|
||||
t.CUInt64T(dbg_p0), t.CUInt64T(dbg_p0n))
|
||||
|
||||
# 声明 LLVM va_start/va_end intrinsic(供 *args 函数体内使用)
|
||||
# declare void @llvm.va_start(i8*)
|
||||
@@ -590,6 +598,26 @@ class Translator:
|
||||
return
|
||||
if _mbuddy is None:
|
||||
return
|
||||
# 诊断(builtins.vp dump 卡死根因排查,仅 stub 模式打印一次):
|
||||
# 模块函数清单 + 每个函数首个参数地址/Next 值(步数上限防成环死循环)。
|
||||
# 确认 printf declare 的创建上下文与 Params 链损坏状态。
|
||||
if mode == llvmlite.OUTPUT_STUB:
|
||||
dbg_f: llvmlite.Function | t.CPtr = llvmlite.module_get_func_head(self.Module)
|
||||
dbg_steps: int = 0
|
||||
while dbg_f is not None:
|
||||
dbg_steps += 1
|
||||
if dbg_steps > 100000:
|
||||
stdio.printf("[DIAG] 模块函数链遍历超限(dump_ir 诊断)\n")
|
||||
stdlib.exit(1)
|
||||
dbg_name: str = llvmlite.function_get_name(dbg_f)
|
||||
dbg_p: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(dbg_f)
|
||||
if dbg_p is not None:
|
||||
dbg_pn: llvmlite.Param | t.CPtr = llvmlite.param_get_next(dbg_p)
|
||||
stdio.printf("[DIAG] 模块函数: %s param0=%llu next=%llu\n",
|
||||
dbg_name, t.CUInt64T(dbg_p), t.CUInt64T(dbg_pn))
|
||||
else:
|
||||
stdio.printf("[DIAG] 模块函数: %s (无参数)\n", dbg_name)
|
||||
dbg_f = llvmlite.function_get_next(dbg_f)
|
||||
buf[0] = '\0'
|
||||
llvmlite.LLVMModulePrint(buf, size, self.Module, _mbuddy, mode)
|
||||
|
||||
|
||||
@@ -827,6 +827,19 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
|
||||
failed += 1
|
||||
continue
|
||||
|
||||
# 诊断(builtins.vp dump 卡死根因排查):pre_rc 哨兵在 translate 前,
|
||||
# 覆盖不到 translate 期间的 AST/IR 写穿。dump 前立即检查存活块
|
||||
# header/canary(rc=6 块尾 canary 损坏=越界写穿数据区),把"dump
|
||||
# 时链表成环卡死"变成"定位到 translate 期间写穿发生的文件"。
|
||||
post_rc: t.CInt = mb.check_alive_blocks(mark1)
|
||||
if post_rc != 0:
|
||||
fb: str = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024,
|
||||
"内存损坏(translate后存活块, rc=%d): %s", post_rc, file_path)
|
||||
VLogger.error(fb, "Phase1")
|
||||
stdlib.exit(1)
|
||||
|
||||
# dump stub IR(declarations only)
|
||||
PHASE1_IR_SIZE: t.CSizeT = 1048576
|
||||
stub_buf: bytes = stdlib.malloc(PHASE1_IR_SIZE)
|
||||
|
||||
Reference in new issue
Block a user