【问题标题】:Clang 8 with MinGW-w64: How do I use address- & UB sanitizers?带有 MinGW-w64 的 Clang 8:如何使用地址和 UB 消毒剂?
【发布时间】:2019-08-24 02:35:06
【问题描述】:

Clang 8 release notes 有这个很有希望的线路:

  • 允许在 MinGW 上使用 Address Sanitizer 和 Undefined Behavior Sanitizer。

但是,我无法弄清楚如何正确使用它们。

我正在使用带有 MSYS2 MinGW GCC 的 Clang 8.0.0。确切的细节在问题的底部。

我正在尝试编译以下最少的代码:

1.cpp

#include <iostream>

int main()
{
    // Testing ubsan
    int x = 0x7fffffff;
    x++;
    std::cout << x << std::endl;

    // Testing asan
    int *y = new int;
    delete y;
    std::cout << *y << std::endl;
}

这是-fsanitize=address 的结果:

# /z/Lander/LLVM/bin/clang++ -target x86_64-w64-windows-gnu -fsanitize=address 1.cpp
Z:\Lander\msys2\mingw64\bin\ld.exe: cannot find Z:\Lander\LLVM\lib\clang\8.0.0\lib\windows\libclang_rt.asan_dynamic-x86_64.dll.a: No such file or directory
Z:\Lander\msys2\mingw64\bin\ld.exe: cannot find Z:\Lander\LLVM\lib\clang\8.0.0\lib\windows\libclang_rt.asan_dynamic_runtime_thunk-x86_64.a: No such file or directory
Z:\Lander\msys2\mingw64\bin\ld.exe: cannot find Z:\Lander\LLVM\lib\clang\8.0.0\lib\windows\libclang_rt.asan_dynamic_runtime_thunk-x86_64.a: No such file or directory
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

这里是-fsanitize=undefined

# /z/Lander/LLVM/bin/clang++ -target x86_64-w64-windows-gnu -fsanitize=undefined 1.cpp
Warning: corrupt .drectve at end of def file
Z:\Lander\msys2\tmp\1-13f09e.o:1.cpp:(.text+0x9f): undefined reference to `__ubsan_handle_add_overflow'
Z:\Lander\msys2\tmp\1-13f09e.o:1.cpp:(.text+0xef): undefined reference to `__ubsan_handle_type_mismatch_v1'
Z:\Lander\msys2\tmp\1-13f09e.o:1.cpp:(.text+0x148): undefined reference to `__ubsan_handle_type_mismatch_v1'
Z:\Lander\msys2\tmp\1-13f09e.o:1.cpp:(.text+0x196): undefined reference to `__ubsan_handle_type_mismatch_v1'
Z:\Lander\msys2\tmp\1-13f09e.o:1.cpp:(.text+0x1df): undefined reference to `__ubsan_handle_type_mismatch_v1'
Z:\Lander\msys2\tmp\1-13f09e.o:1.cpp:(.text+0x22c): undefined reference to `__ubsan_handle_type_mismatch_v1'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

这是Z:\Lander\LLVM\lib\clang\8.0.0\lib\windows\ 的内容,它在其中查找库:

clang_rt.asan-preinit-x86_64.lib
clang_rt.asan-x86_64.lib
clang_rt.asan_cxx-x86_64.lib
clang_rt.asan_dll_thunk-x86_64.lib
clang_rt.asan_dynamic-x86_64.dll
clang_rt.asan_dynamic-x86_64.lib
clang_rt.asan_dynamic_runtime_thunk-x86_64.lib
clang_rt.builtins-x86_64.lib
clang_rt.fuzzer-x86_64.lib
clang_rt.fuzzer_no_main-x86_64.lib
clang_rt.profile-x86_64.lib
clang_rt.stats-x86_64.lib
clang_rt.stats_client-x86_64.lib
clang_rt.ubsan_standalone-x86_64.lib
clang_rt.ubsan_standalone_cxx-x86_64.lib

这看起来不正确,因为 MinGW GCC 通常适用于 .a 库,而不是 .lib

我尝试从该目录手动链接各种库。

对于 asan,我设法摆脱了编译器错误,但 asan 本身似乎没有发出任何诊断信息:

# /z/Lander/LLVM/bin/clang++ -target x86_64-w64-windows-gnu -fsanitize=address 1.cpp -c
# /z/Lander/LLVM/bin/clang++ -target x86_64-w64-windows-gnu 1.o /z/Lander/LLVM/lib/clang/8.0.0/lib/windows/clang_rt.asan_dynamic-x86_64.lib
# ./a.exe
-2147483648
5089296         <- expected a diagnostic here

对于 ubsan,我尝试链接到 clang_rt.ubsan_standalone-x86_64.lib,但得到了更多未定义的引用和几个 Warning: corrupt .drectve at end of def file

我对@9​​87654336@ 做了一些研究,this question 表明这意味着我正在链接不兼容的 MSVC 库。

这里发生了什么?我应该如何使用 asan 和 ubsan?


以上所有命令均从 MSYS2 终端运行,在 Windows 7 x64 上运行。

我的目标是 x86_64 并使用 MSYS2 中可用的最新 GCC:

# g++ --version
g++.exe (Rev2, Built by MSYS2 project) 8.3.0

MSYS2 的 Clang 似乎没有捆绑 asan 和 ubsan 库,所以我使用的是来自 llvm.org 的官方版本:

# /z/Lander/LLVM/bin/clang++ --version
clang version 8.0.0 (tags/RELEASE_800/final)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: Z:\Lander\LLVM\bin

我正在使用-target x86_64-w64-windows-gnu,因为否则 Clang 会尝试使用我没有的 MSVC 安装。这个特定的三元组是 MSYS2 clang 报告给--version 的。

【问题讨论】:

  • 出于类似原因,我在 VirtualBox Linux 映像中运行消毒剂。那里一切正常。
  • msys2 上是否有单独的 libasan 包?
  • @smerlin 显然没有。我尝试在包列表中搜索clang,llvm,san,安装了一些看起来很有希望的包,但没有运气。
  • 你找到解决办法了吗?
  • @amithks 不..

标签: c++ clang mingw-w64 address-sanitizer ubsan


【解决方案1】:

我找到了让 UBsan 工作的方法,但不是 Asan。

事实证明,即使没有 libubsan,UBsan 也可以运行。您需要使用以下标志:

-fsanitize=undefined -fsanitize-undefined-trap-on-error

这样,错误是通过“非法指令”崩溃而不是通过发出漂亮的诊断来报告的,但总比没有好。

GCC 和 Clang 都支持此标志。

GCC manual:

-fsanitize-undefined-trap-on-error

-fsanitize-undefined-trap-on-error 选项指示编译器使用 __builtin_trap 而不是 libubsan 库例程报告未定义的行为。这样做的好处是不需要 libubsan 库并且没有链接,因此即使在独立环境中也可以使用。

【讨论】:

    【解决方案2】:

    ASAN 确实适用于 Windows。

    为了避免以下错误:

    C:/msys64/mingw64/bin/ld: cannot find C:/msys64/mingw64/lib/clang/13.0.0/lib/windows/libclang_rt.asan_dynamic-x86_64.dll.a: No such file or directory
    C:/msys64/mingw64/bin/ld: cannot find C:/msys64/mingw64/lib/clang/13.0.0/lib/windows/libclang_rt.asan_dynamic_runtime_thunk-x86_64.a: No such file or directory
    

    使用/clang64/bin/clang 代替/mingw64/bin/clang。安装它:

    pacman -S mingw-w64-clang-x86_64-clang
    

    https://www.msys2.org/docs/environments/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-06
      • 2016-07-28
      • 1970-01-01
      • 2020-07-27
      • 2017-09-17
      • 2017-02-13
      • 2021-03-07
      相关资源
      最近更新 更多