c++ 使用MinGW-w 64发出叮当声8:如何使用地址- & UB消毒剂?

ubof19bj  于 2023-03-14  发布在  其他
关注(0)|答案(3)|浏览(433)

Clang 8发布说明中有这样一行很有前景:

  • 允许在MinGW上使用地址过滤器和未定义的行为过滤器。

然而,我不知道如何正确地使用这些。
我使用的是带有MSYS2 MinGW GCC的Clang 8.0.0。确切的细节在问题的底部。
我试图编译以下最小的一段代码:

1.国家方案预算

#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
我对Warning: corrupt .drectve at end of def file做了一些研究,this question表明这意味着我链接了不兼容的MSVC库。
这是怎么回事?我要怎么用峨山和峨山?
上述所有命令均从运行Windows 7 x64的MSYS2终端运行。
我的目标是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安装,而我没有MSVC安装。这个特定的三元组是MSYS2 Clang报告--version的响应。

cyej8jka

cyej8jka1#

我找到了让宇布桑成功的方法,但不是峨山。
事实证明,即使没有libubsan,UBsan也可以正常工作。

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

这样,错误是通过“非法指令”崩溃来报告的,而不是通过发出漂亮的诊断来报告的,但总比什么都没有好。
GCC和Clang都支持此标志。
GCC manual:

一月一日

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

6vl6ewon

6vl6ewon2#

Windows上支持清理程序(地址、UB等)的编译器

要从现在(3/2023)起在Windows上使用杀毒程序,您需要:

  • 安装了Visual Studio 2019或更高版本的MSVC(with AddressSanitizer installed
  • 仅支持地址消毒程序
  • 使用here指令的良好StackOverflow应答
  • Visual Studio上的任何叮当声
  • 可以在Visual Studio 2019或更高版本上安装via the installer
  • Microsoft C++库需要Clang编译器8.0.0或更高版本,因此任何与VS兼容的编译器都应该附带地址和UB清理程序。
  • WSL(适用于Linux的Windows子系统)中的任何gcc或clang编译器
  • 应支持所有清理程序(地址、线程、内存和UB)
  • 要求您能够在Linux环境中编译和运行代码。
  • MSYS2 CLANG64 environment上使用带有clang和libc++ as of 4/2021的MSYS 2
  • 支持UB和地址清理程序(不支持线程和内存清理程序)。
  • 其他clang变体不支持清理程序,即libstdc++版本,如UCRT 64。在尝试将清理程序与这些clang包一起使用时,会出现链接器错误。
  • MSYS2 gcc does not support AddressSanitizer .

Visual Studio AddressSanitizer或Clang的安装应该很容易按照指南进行WSL也有很多来自微软和其他第三方网站的指南,因此,我将只介绍MSYS 2上的安装。MSYS 2包括许多不同的环境,每个环境都有自己的clang包,并且只有一个clang变体(libc++)支持消毒剂。

如何使用地址和UB杀毒程序安装MSYS 2 clang

1.使用MSYS2 Getting started guide之后的安装程序安装MSYS 2。注意如果您勾选框 Run MSYS 2 now,则默认情况下安装程序将启动杀毒程序不兼容环境UCRT 64。
1.从“开始”菜单启动MSYS 2 CLANG 64终端环境。正确的终端具有前缀<username>@<computer_name> CLANG64
1.使用软件包管理器pacman -SyuMSYS2 Update guide here)更新MSYS 2
1.在某些情况下,尤其是首次安装时,更新过程需要关闭终端来更新一些核心包。如果发生这种情况,请再次启动CLANG 64终端并再次运行pacman -Syu****来更新非核心包。
1.接下来,我们需要安装正确的clang变体,这可以通过包管理器命令pacman -S mingw-w64-clang-x86_64-clang来完成。
1.安装完成后,运行clang --version检查是否安装了正确的变体。
1.如果你得到一个错误-bash: clang: command not found或类似的东西,你很可能是在错误的环境。切换到CLANG 64环境,因为mingw-w64-clang-x86_64-clang包安装clang在那里。
现在,在CLANG 64 MSYS 2环境中,您可以使用clangclang++编译器的-fsanitize=address-fsanitize=undefined选项编译地址和UB清理程序的代码。例如,我们可以使用以下程序测试AddressSanitizer:

int main()
{
    int* const heapOverflow = new int[5]{};
    heapOverflow[5] = 0;
}

clang++编译并运行,您应该会得到一个AddressSanitizer错误:

$ clang++ -fsanitize=address heapoverflow.cpp -o heapoverflow`
$./heapoverflow

=================================================================
==17384==ERROR: AddressSanitizer: heap-buffer-overflow on address
...
qpgpyjmq

qpgpyjmq3#

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/

相关问题