Clang 在 Windows 上使用 Address Sanitizer 在链接时失败。

huangapple go评论93阅读模式
英文:

Clang with Address Sanitizer on Windows fails at link time

问题

我有以下设置:

  • clang:

    clang版本16.0.6
    目标:x86_64-pc-windows-msvc
    线程模型:posix
    
  • Windows(不确定是否相关):

    Windows 10版本22H2(操作系统构建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: 警告:CMakeFiles/asan-test.dir/asan-test.c.obj:本地定义的符号已导入:malloc(定义在clang_rt.asan-x86_64.lib(asan_malloc_win.cpp.obj)中)[LNK4217]
lld-link: 警告:CMakeFiles/asan-test.dir/asan-test.c.obj:本地定义的符号已导入:free(定义在clang_rt.asan-x86_64.lib(asan_malloc_win.cpp.obj)中)[LNK4217]
lld-link: 警告:CMakeFiles/asan-test.dir/asan-test.c.obj:本地定义的符号已导入:fclose(定义在libucrt.lib(fclose.obj)中)[LNK4217]
lld-link: 警告:CMakeFiles/asan-test.dir/asan-test.c.obj:本地定义的符号已导入:__stdio_common_vsprintf(定义在libucrt.lib(output.obj)中)[LNK4217]
lld-link: 错误:未定义的符号:__declspec(dllimport) fopen
>>> 被引用于 <...>\asan-test\asan-test.c:8
>>>               CMakeFiles/asan-test.dir/asan-test.c.obj:(main)

我不确定如何解决这个问题。我找不到类似的东西,或者可能我没有在正确的地方查找。

英文:

I have the following setup:

  • clang:

    clang version 16.0.6
    Target: x86_64-pc-windows-msvc
    Thread model: posix
    
  • windows (not sure if relevant):

    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)
    
  • and finally the source code file 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;
    }
    

The second command fails at link time:

cmake -S . -B build-windows -D CMAKE_C_COMPILER=clang -G "Unix Makefiles"
cmake --build build-windows

The output contains the following 4 warnings and 1 error:

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)

I'm not sure how to approach this problem. I couldn't find anything similar, or maybe I didn't look in the right places.

答案1

得分: 0

I got it working. I came across this page from the Windows port of Address Sanitizer, and the takeaway is that the Windows port...

  • does not (yet) work with the debug versions of the CRT: /MTd and /MDd
  • the linker does not accept -fsanitize=address, rather, it needs to link against, for example, clang_rt.asan-x86_64.lib

I changed the setup as follows:

  • in CMakeLists.txt, I replaced
    target_link_options(asan-test PRIVATE -fsanitize=address)
    

    with

    target_link_libraries(asan-test PRIVATE clang_rt.asan-x86_64)
    
  • in the cmake generation step, I added
    -D CMAKE_BUILD_TYPE=Release
    
英文:

I got it working. I came across this page from the Windows port of Address Sanitizer, and the takeaway is that the Windows port...

  • does not (yet) work with the debug versions of the CRT: /MTd and /MDd
  • the linker does not accept -fsanitize=address, rather, it needs to link against, for example, clang_rt.asan-x86_64.lib

I changed the setup as follows:

  • in CMakeLists.txt, I replaced
    target_link_options(asan-test PRIVATE -fsanitize=address)
    

    with

    target_link_libraries(asan-test PRIVATE clang_rt.asan-x86_64)
    
  • in the cmake generation step, I added
    -D CMAKE_BUILD_TYPE=Release
    

huangapple
  • 本文由 发表于 2023年7月17日 16:09:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76702561.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定