From 9b190ac73ea17ddfa617cc6ee0c5e6f566ba8e2c Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 15 Aug 2026 13:25:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(TPC):=20--asan=20=E5=81=87=E7=94=9F?= =?UTF-8?q?=E6=95=88=E4=BF=AE=E5=A4=8D=20=E2=80=94=E2=80=94=20opt=20-passe?= =?UTF-8?q?s=3Dasan=20=E9=9C=80=E5=85=88=20forceattrs=20=E5=8A=A0=20saniti?= =?UTF-8?q?ze=5Faddress=20=E5=B1=9E=E6=80=A7=EF=BC=88LLVM>=3D20=20?= =?UTF-8?q?=E5=8F=AA=E6=8F=92=E6=A1=A9=E5=B8=A6=E5=B1=9E=E6=80=A7=E5=87=BD?= =?UTF-8?q?=E6=95=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Projectrans/Phase2Translator.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/Projectrans/Phase2Translator.py b/lib/Projectrans/Phase2Translator.py index 6b21762..53c3bb8 100644 --- a/lib/Projectrans/Phase2Translator.py +++ b/lib/Projectrans/Phase2Translator.py @@ -1198,9 +1198,13 @@ class Phase2Translator: cwd: str | None = None) -> subprocess.CompletedProcess: """编译单个 .ll 为 obj。 - ASan 模式(TPC_ASAN=1)下先对 IR 执行 opt -passes=asan 插桩: + ASan 模式(TPC_ASAN=1)下先对 IR 执行 opt 插桩: 检测 stdlib 堆/栈/全局越界写与垃圾指针解引用(MemBuddy pool 内部 由块尾 canary 覆盖,两者互补)。opt 失败返回其结果(returncode!=0)。 + + LLVM >= 20 起 opt -passes=asan 只对带 sanitize_address 函数属性的 + 函数插桩(clang -fsanitize=address 自动加;手写 IR 没有)—— + 先 forceattrs 批量加属性再 asan,否则只链接 runtime 不插桩。 """ compile_input = ll_path if self.asan_mode: @@ -1208,7 +1212,8 @@ class Phase2Translator: # -asan-globals=false:TPC 对全局变量(如各模块 _g_gen)用直接地址寻址, # ASan 全局 redzone 重定位后引用错位会导致读到垃圾指针(如 # register_struct 的 self=0xbebebebe...)。先关闭全局插桩排除该因素。 - opt_cmd = ['opt', '-passes=asan', '-asan-globals=false', ll_path, '-o', asan_ll] + opt_cmd = ['opt', '-passes=forceattrs,asan', '-force-attribute=sanitize_address', + '-asan-globals=false', ll_path, '-o', asan_ll] opt_r = subprocess.run(opt_cmd, capture_output=True, text=True, cwd=cwd) if opt_r.returncode != 0: _vlog().error(f" opt ASan 插桩失败: {opt_r.stderr.strip()}")