From 0db1ccd1bbab0d39f740c4c79fbbecda3666cd41 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 19 Aug 2026 08:47:32 +0800 Subject: [PATCH] =?UTF-8?q?refactor(asan):=20TPC=5FASAN=20=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E5=8F=98=E9=87=8F=E6=94=B9=20args=20=E7=9B=B4?= =?UTF-8?q?=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --asan 不再写 TPC_ASAN 环境变量,改为 Config 解析后直接经 asan_mode=args.asan 传给 Phase2Translator(主进程 .ll→.obj 插桩与 链接 -fsanitize=address 均读 self.asan_mode),消除环境变量在 worker 子进程/外部调用链下的不可靠性。 --- lib/Projectrans/Config.py | 8 ++++---- lib/Projectrans/Phase2Translator.py | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/Projectrans/Config.py b/lib/Projectrans/Config.py index 5e080e4..ba73936 100644 --- a/lib/Projectrans/Config.py +++ b/lib/Projectrans/Config.py @@ -152,10 +152,10 @@ def main() -> None: args: argparse.Namespace = parser.parse_args() - # ASan 模式(--asan):透传 TPC_ASAN=1 供 Phase2Translator 及 worker 子进程 - # 检测(compile_ll_to_obj 先 opt -passes=asan 插桩,链接追加 -fsanitize=address)。 + # ASan 模式(--asan):直接经 args 传给 Phase2Translator(compile_ll_to_obj + # 先 opt -passes=asan 插桩,链接追加 -fsanitize=address)。不再用 TPC_ASAN + # 环境变量透传——环境变量在 worker 子进程/外部调用链下不可靠。 if args.asan: - os.environ['TPC_ASAN'] = '1' _vlog().info('ASan 模式已启用(opt -passes=asan + -fsanitize=address)', 'asan') project_file: str | None = args.project @@ -300,7 +300,7 @@ def main() -> None: except: pass _vlog().info(f"includes.binary: 已清空 {precompiled_dir} ({cleared} 个文件)") - trans: Phase2Translator = Phase2Translator(src, temp_dir, output_dir, compile_cmd=cc_cmd, compile_flags=cc_flags, linker_cmd=linker_cmd, linker_flags=linker_flags, linker_output=linker_output, include_dirs=project_include_dirs, target_triple=target_triple, target_datalayout=target_datalayout, force_recompile_includes=force_recompile_includes) + trans: Phase2Translator = Phase2Translator(src, temp_dir, output_dir, compile_cmd=cc_cmd, compile_flags=cc_flags, linker_cmd=linker_cmd, linker_flags=linker_flags, linker_output=linker_output, include_dirs=project_include_dirs, target_triple=target_triple, target_datalayout=target_datalayout, force_recompile_includes=force_recompile_includes, asan_mode=args.asan) trans.sha1_map = Load_sha1_map(temp_dir) trans.slice_level = slice_level trans.run() diff --git a/lib/Projectrans/Phase2Translator.py b/lib/Projectrans/Phase2Translator.py index ac73d5c..f2b8130 100644 --- a/lib/Projectrans/Phase2Translator.py +++ b/lib/Projectrans/Phase2Translator.py @@ -445,7 +445,7 @@ class Phase2Translator: _include_sha1_cache: dict[str, str] = {} _include_exist_cache: dict[str, bool] = {} - def __init__(self, src_root: str, temp_dir: str, output_dir: str, compile_cmd: str = 'llc', compile_flags: list[str] | None = None, linker_cmd: str | None = None, linker_flags: list[str] | None = None, linker_output: str | None = None, include_dirs: list[str] | None = None, entry_files: list[str] | None = None, target_triple: str | None = None, target_datalayout: str | None = None, force_recompile_includes: bool = False, build_pyi_cache: bool = True) -> None: + def __init__(self, src_root: str, temp_dir: str, output_dir: str, compile_cmd: str = 'llc', compile_flags: list[str] | None = None, linker_cmd: str | None = None, linker_flags: list[str] | None = None, linker_output: str | None = None, include_dirs: list[str] | None = None, entry_files: list[str] | None = None, target_triple: str | None = None, target_datalayout: str | None = None, force_recompile_includes: bool = False, build_pyi_cache: bool = True, asan_mode: bool = False) -> None: self.src_root = os.path.abspath(src_root) self.temp_dir = os.path.abspath(temp_dir) self.output_dir = os.path.abspath(output_dir) @@ -462,11 +462,12 @@ class Phase2Translator: self.linker_cmd = linker_cmd self.linker_flags = linker_flags or [] self.linker_output = linker_output - # ASan 模式:TPC_ASAN=1 时对全部 .ll 做 opt -passes=asan 插桩并链接 libasan。 + # ASan 模式:由 Config 的 --asan 参数直传(不再用 TPC_ASAN 环境变量, + # 环境变量在 worker 子进程/外部调用链下不可靠)。 # 检测 stdlib 堆/栈/全局越界与垃圾指针(MemBuddy pool 内部由 canary 覆盖)。 # 注意:mingw64 的 clang 不提供 ASan runtime(libclang_rt.asan 缺失), # 必须使用 clang64 环境(自带 asan_dynamic runtime),PATH 前置 clang64/bin。 - self.asan_mode = os.environ.get('TPC_ASAN') == '1' + self.asan_mode = asan_mode if self.asan_mode: _clang64_bin = r'D:\msys64\clang64\bin' if os.path.isdir(_clang64_bin): @@ -1573,7 +1574,7 @@ class Phase2Translator: cwd: str | None = None) -> subprocess.CompletedProcess: """编译单个 .ll 为 obj。 - ASan 模式(TPC_ASAN=1)下先对 IR 执行 opt 插桩: + ASan 模式(--asan)下先对 IR 执行 opt 插桩: 检测 stdlib 堆/栈/全局越界写与垃圾指针解引用(MemBuddy pool 内部 由块尾 canary 覆盖,两者互补)。opt 失败返回其结果(returncode!=0)。