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()}")