Windows下Clang结合Address Sanitizer编译链接失败问题
链接阶段报错:undefined symbol: __declspec(dllimport) fopen 及LNK4217警告
环境配置
- Clang版本:
clang version 16.0.6 Target: x86_64-pc-windows-msvc Thread model: posix
- Windows系统:
Windows 10 Version 22H2 (OS Build 19045.3086)
- CMakeLists.txt:
cmake_minimum_required(VERSION 3.22) project(asan-test C) add_executable(asan-test) target_sources(asan-test PRIVATE asan-test.c) target_compile_options(asan-test PRIVATE -fsanitize=address) target_link_options(asan-test PRIVATE -fsanitize=address) target_compile_definitions(asan-test PRIVATE _CRT_SECURE_NO_WARNINGS)
- 源代码文件
asan-test.c:
#include <stdio.h> #include <stdlib.h> int main() { const int kBufferSize = 255; char* buffer = malloc(kBufferSize * sizeof(char)); FILE* fi = fopen("duck.txt", "r"); free(buffer); fclose(fi); return 0; }
执行命令
cmake -S . -B build-windows -D CMAKE_C_COMPILER=clang -G "Unix Makefiles" cmake --build build-windows
链接阶段输出(4条警告+1条错误)
警告信息
lld-link: warning: CMakeFiles/asan-test.dir/asan-test.c.obj: locally defined symbol imported: malloc (defined in clang_rt.asan-x86_64.lib(asan_malloc_win.cpp.obj)) [LNK4217] lld-link: warning: CMakeFiles/asan-test.dir/asan-test.c.obj: locally defined symbol imported: free (defined in clang_rt.asan-x86_64.lib(asan_malloc_win.cpp.obj)) [LNK4217] lld-link: warning: CMakeFiles/asan-test.dir/asan-test.c.obj: locally defined symbol imported: fclose (defined in libucrt.lib(fclose.obj)) [LNK4217] lld-link: warning: CMakeFiles/asan-test.dir/asan-test.c.obj: locally defined symbol imported: __stdio_common_vsprintf (defined in libucrt.lib(output.obj)) [LNK4217]
错误信息
lld-link: error: undefined symbol: __declspec(dllimport) fopen >>> referenced by <...>\asan-test\asan-test.c:8 >>> CMakeFiles/asan-test.dir/asan-test.c.obj:(main)
解决方法
更换CMake生成器:Windows环境下使用
Unix Makefiles生成器搭配Clang+ASAN易出现CRT库链接冲突,建议改用Ninja或Visual Studio生成器,示例命令:cmake -S . -B build-windows -D CMAKE_C_COMPILER=clang -G Ninja针对Visual Studio环境:
cmake -S . -B build-windows -D CMAKE_C_COMPILER=clang-cl -G "Visual Studio 17 2022" -A x64显式指定CRT链接方式:ASAN在Windows上通常依赖动态CRT,在CMakeLists.txt中添加编译定义强制使用动态CRT:
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MDd") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MD")或者直接针对目标设置:
target_compile_options(asan-test PRIVATE $<$<CONFIG:Debug>:/MDd> $<$<CONFIG:Release>:/MD>)检查Clang环境变量:确保Clang的bin目录、对应ASAN库目录已加入系统环境变量,避免链接时无法找到完整的CRT和ASAN依赖库。
内容的提问来源于stack exchange,提问作者haidahaida
相关产品推荐
相关产品推荐

