From 0cb0a1281046fc87b3ca04bc90ee0102689c082e Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 18 Aug 2026 08:17:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(phase1):=20=E5=8A=A0=20translate=20?= =?UTF-8?q?=E5=90=8E=E5=AD=98=E6=B4=BB=E5=9D=97=E6=A3=80=E6=9F=A5=20+=20pr?= =?UTF-8?q?intf=20Params=20=E9=93=BE=E5=88=9B=E5=BB=BA=E5=8D=B3=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=20+=20dump=20=E5=87=BD=E6=95=B0=E6=B8=85=E5=8D=95?= =?UTF-8?q?=E8=AF=8A=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 定位越界写穿文件) --- App/lib/core/Handles/HandlesTranslator.vp | 28 +++++++++++++++++++++++ App/lib/core/Phase1Main.vp | 13 +++++++++++ 2 files changed, 41 insertions(+) diff --git a/App/lib/core/Handles/HandlesTranslator.vp b/App/lib/core/Handles/HandlesTranslator.vp index f6aee51..fc5e903 100644 --- a/App/lib/core/Handles/HandlesTranslator.vp +++ b/App/lib/core/Handles/HandlesTranslator.vp @@ -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) diff --git a/App/lib/core/Phase1Main.vp b/App/lib/core/Phase1Main.vp index 23a3cbe..9f96ab1 100644 --- a/App/lib/core/Phase1Main.vp +++ b/App/lib/core/Phase1Main.vp @@ -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)