feat(traceback): 运行期调用栈显示 callsite 行号(编译器旁文件 + 链接后 objdump 归一)

MLIR 后端下 mlirlite 只记录 DI 不输出、且 mlir-translate 不产 !dbg(实测),
导致我方 .vp 函数在最终 exe 无任何 .debug_line(<exe>.stackmap 只剩 mingw CRT
的 C 源记录)→ 用户代码帧只能显示 line 0。

改为 Route A:--traceback 时编译器记录每函数(F)与每次调用(C,含调用点行),
写 <sha1>.vpcall;链接后 WriteStackMap 用 llvm-objdump 反汇编,把 callq 的
返回地址 RVA 按 (调用方,被调方,出现序号) 匹配到调用点行,并在函数入口写定义行
兜底;合并进现有 .stackmap 格式。运行期 traceback.vp 不改。

验收:PtrOpProbe --traceback 生成 427 条我方记录(抽查 main 的 malloc/printf
等行号与源码逐一吻合);非 --traceback 构建零旁文件、产物与运行结果不变。
This commit is contained in:
TermiNexus committed 2026-10-04 22:38:02 +08:00
1 parent 4236127956
commit 9717ce0107
4 files changed
+667 -9

No files matched your search

+8
View File
@@ -1169,6 +1169,14 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str,
stdlib.free(full_path_p1)
stdlib.free(full_buf_p1)
# --traceback: 取出本模块的调试调用点记录(mlirlite 累积)并写 <sha1>.vpcall,
# 供链接后 WriteStackMap 结合 objdump 还原调用点行号。关闭时不产生任何旁文件。
if BuildPipeline._traceback_mode != 0:
vpcall_text_p1: str = mlirlite.DebugTakeText()
if vpcall_text_p1 is not None:
BuildPipeline.WriteCallSidecar(temp_dir, sha1, vpcall_text_p1)
stdlib.free(vpcall_text_p1)
# 计时点 3:dump(stub+text)完成;输出单文件三段耗时
t_f3: uint64 = w32.win32base.GetTickCount64()
VLogger.info(f"[{i+1}/{loop_n_b}] 翻译: {file_path} (parse={t_f1-t_f0} ms, translate={t_f2-t_f1} ms, dump={t_f3-t_f2} ms, total={t_f3-t_f0} ms)", "Phase1")