Clang 8 发行说明有这样一条有希望的行:
- 允许在 MinGW 上使用 Address Sanitizer 和 Undefined Behavior Sanitizer。
但是,我无法弄清楚如何正确使用它们。
我将 Clang 8.0.0 与 MSYS2 MinGW GCC 一起使用。确切的细节在问题的底部。
我正在尝试编译以下最少的代码:
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
.
我做了一些研究Warning: corrupt .drectve at end of def file
,这个问题表明这意味着我正在链接不兼容的 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
。