尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

【Bug已解决】[Feature Request] Add ONNX Runtime builds and drops for Windows + clang + ASAN 解决方案

【Bug已解决】[Feature Request] Add ONNX Runtime builds and drops for Windows + clang + ASAN 解决方案 【Bug已解决】[Feature Request] Add ONNX Runtime builds and drops for Windows clang ASAN 解决方案一、现象长什么样想在 Windows 上用clang ASANAddressSanitizer构建 ONNX Runtime 来做内存错误检测捕捉 use-after-free、heap-buffer-overflow 等发现官方既没有提供这种构建产物drop构建脚本也不支持这个组合——直接用 clang-cl -fsanitizeaddress编会失败。现象# 现象 A构建脚本不识别 clangASAN 组合 # CMake Error: ORT only supports MSVC or clang for Windows, but # ASAN option is not wired for clang-cl on Windows # 现象 B强行加 -fsanitizeaddress 编到一半挂 # clang-cl: error: unsupported option -fsanitizeaddress for this target # 或链接阶段找不到 ASAN 运行时 (clang_rt.asan.lib) # 现象 C缺少预编译 drop # 官方只提供 MSVC 的 release/debug drop想要 clangASAN 的只能自己改 # 构建系统而构建系统对这套组合完全没有分支支持最坑的是现象 B用户以为“clang 支持 ASAN加上就行”结果链接阶段缺clang_rt.asan.lib因为 Windows 下 clang 的 ASAN 运行时库路径和 Linux/macOS 不同构建脚本没处理。二、背景ONNX Runtime 的构建系统CMake对 Windows 主要支持 MSVC 工具链clang 作为可选clang-cl 兼容 MSVC 接口。ASAN 在 Windows 上由 clang 提供-fsanitizeaddress 链接clang_rt.asan-{arch}.lib 运行时clang_rt.asan_dynamic-*.dll但这套配置和 Linux/macOS 不同Linux/macOS-fsanitizeaddress自动链接libasan无需额外库路径Windows/clang-cl需要显式把 clang 的lib目录加入链接路径并链接clang_rt.asan.lib静态或clang_rt.asan_dynamic.lib动态否则链接失败。ORT 的 CMake 在 Windows 分支里只配了 MSVC 的运行时没为 clangASAN 加这些链接参数也没提供现成的 drop。于是“想用 ASAN 抓 Windows 上的内存 bug”这条路被堵死。这是构建系统/工具链审查里典型的坑新工具链组合clangASAN on Windows未被构建系统支持且 ASAN 运行时库路径的跨平台差异没被处理。三、根因CMake 未为 Windowsclang 接 ASAN 选项ORT_ENABLE_ASAN只在 Linux/macOS 分支设置-fsanitizeaddressWindows 分支漏了。ASAN 运行时库路径未配置Windows/clang 需要把 clang 的lib/clang/ver/lib/windows加入link_directories并链接clang_rt.asan*.libCMake 没做。缺少预编译 drop官方发布只覆盖 MSVCclangASAN 既无支持也无产物用户只能自己改构建系统。本质是构建系统未支持 WindowsclangASAN 组合缺选项接入与 ASAN 运行时库链接且缺预编译 drop。四、最小可运行复现下面用 Python 模拟“构建系统在 Windowsclang 下漏接 ASAN 链接参数导致链接失败”def configure_build_buggy(os_name, compiler, enable_asan): buggy: ASAN 只在非 Windows 接入。 flags, libs, link_dirs [], [], [] if enable_asan: if os_name ! Windows: # Windows 分支漏了 flags.append(-fsanitizeaddress) libs.append(libasan) return flags, libs, link_dirs def configure_build_fixed(os_name, compiler, enable_asan, clang_lib_dir): fixed: Windowsclang 也接入 ASAN并配运行时库路径。 flags, libs, link_dirs [], [], [] if enable_asan: flags.append(-fsanitizeaddress) if os_name Windows and compiler clang: # Windows/clang 需要显式 clang ASAN 运行时库 link_dirs.append(clang_lib_dir) libs.append(clang_rt.asan.lib) else: libs.append(libasan) return flags, libs, link_dirs print(buggy Winclang:, configure_build_buggy(Windows, clang, True)) # 空漏了 print(fixed Winclang:, configure_build_fixed(Windows, clang, True, C:/llvm/lib/clang/18/lib/windows)) # flags 有 asanlibs 有 clang_rt.asan.liblink_dirs 有 clang lib 路径buggy在 Windowsclang 下啥都没加链接必失败fixed正确接入。五、解决方案第一层最小直接修复最小修复CMake 在 Windowsclang 分支也接入 ASAN并配置 clang ASAN 运行时库路径与链接# 修正ORT_ENABLE_ASAN 支持 Windowsclang if(ORT_ENABLE_ASAN) if(WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) add_compile_options(-fsanitizeaddress -fno-omit-frame-pointer) # 找到 clang 的 ASAN 运行时库目录 execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-namelibclang_rt.asan-x86_64.lib OUTPUT_VARIABLE ASAN_LIB) get_filename_component(ASAN_LIB_DIR ${ASAN_LIB} DIRECTORY) link_directories(${ASAN_LIB_DIR}) target_link_libraries(onnxruntime PRIVATE clang_rt.asan.lib) else() add_compile_options(-fsanitizeaddress) target_link_libraries(onnxruntime PRIVATE asan) endif() endif()这一层改动最小Windowsclang 也接 ASAN 并链clang_rt.asan.lib构建恢复。但依赖“每处工具链分支都加对”下看第二层。六、解决方案第二层结构性改进把“各工具链组合的 ASAN 配置”固化成单一事实来源。下面这个 dataclass 集中管理工具链→ASAN 配置的映射CMake 和校验共享from dataclasses import dataclass, field from typing import Dict, Tuple dataclass class OrtClangAsanPolicy: 单一事实来源工具链组合的 ASAN 构建配置。 # (os, compiler) - (compile_flags, link_libs) _config: Dict[Tuple[str, str], Tuple[list, list]] field(default_factorylambda: { (Linux, clang): ([-fsanitizeaddress], [asan]), (Darwin, clang): ([-fsanitizeaddress], [asan]), (Windows, clang): ([-fsanitizeaddress, -fno-omit-frame-pointer], [clang_rt.asan.lib]), (Windows, MSVC): ([], []), # MSVC ASAN 暂不支持 }) def resolve(self, os_name: str, compiler: str, enable_asan: bool): if not enable_asan: return [], [] key (os_name, compiler) if key not in self._config: raise ValueError(fASAN not supported for {key}) return self._config[key] def assert_supported(self, os_name: str, compiler: str) - None: key (os_name, compiler) if key not in self._config or not self._config[key][0]: raise AssertionError(fno ASAN config for {key})这一层的关键收益组合配置集中所有 (os,compiler) 的 ASAN 配置在_config新增组合只改这里Windowsclang 明确支持clang_rt.asan.lib已入表不支持即报错assert_supported拒绝未配置组合避免静默失败单一事实来源所有工具链 ASAN 约定收口在OrtClangAsanPolicy。七、解决方案第三层断言 / CI 守护把第二层钉成 pytest挂进 CI覆盖 WindowsclangASANimport pytest from your_package.ort_clang_asan import OrtClangAsanPolicy def test_windows_clang_asan_configured(): # 断言 1Windowsclang 有 ASAN 配置且链 clang_rt.asan.lib p OrtClangAsanPolicy() flags, libs p.resolve(Windows, clang, True) assert -fsanitizeaddress in flags assert clang_rt.asan.lib in libs def test_linux_clang_asan_configured(): # 断言 2Linuxclang ASAN 正常 p OrtClangAsanPolicy() flags, libs p.resolve(Linux, clang, True) assert -fsanitizeaddress in flags def test_msvc_asan_unsupported_errors(): # 断言 3MSVC ASAN 未配置必须报错而非静默失败 p OrtClangAsanPolicy() with pytest.raises((ValueError, AssertionError)): p.resolve(Windows, MSVC, True) def test_no_asan_returns_empty(): # 断言 4不开启 ASAN 返回空不影响普通构建 p OrtClangAsanPolicy() assert p.resolve(Windows, clang, False) ([], [])四条断言从“Winclang 配置”“Linux 配置”“MSVC 报错”“不开启为空”四面把工具链支持钉死在 CI。八、排查清单想在 WindowsclangASAN 构建 ORT 失败时CMake 报 ASAN 不支持或链接找不到clang_rt.asan.lib查 Windowsclang 分支是否接入 ASAN现象 A/B。Windows/clang 的 ASAN 运行时库路径是否加入link_directories没加就链接失败现象 B。官方是否提供该组合 drop没有就确认构建系统已支持自行构建。用第二层OrtClangAsanPolicy工具链组合配置集中 不支持即报错。加第三层 pytest断言“Winclang 配置、Linux 配置、MSVC 报错、不开启为空”。ASAN 的运行时库路径跨平台差异大Windows 需显式 clang rt lib构建系统必须逐平台处理。九、小结ONNX Runtime 缺 WindowsclangASAN 构建本质是构建系统只在 Linux/macOS 分支接入 ASANWindowsclang 分支既没加-fsanitizeaddress、也没配置 clang 的clang_rt.asan.lib运行时库路径导致链接失败且缺预编译 drop。修复分三层——第一层 CMake 在 Windowsclang 也接 ASAN 并链clang_rt.asan.lib第二层用OrtClangAsanPolicy这个 dataclass 把各工具链组合的 ASAN 配置收口成单一事实来源不支持即报错第三层用四条 pytest 把“Winclang 配置、Linux 配置、MSVC 报错、不开启为空”钉死在 CI。核心心法ASAN 的运行时库路径跨平台差异大Windows/clang 需显式链接 clang_rt.asan.lib构建系统必须逐平台接入且不支持的组合要明确报错而非静默失败。
返回列表