Clang 8 release notes have this promising line:
- Allow using Address Sanitizer and Undefined Behaviour Sanitizer on MinGW.
However, I unable to figure out how to use those properly.
I'm using Clang 8.0.0 with MSYS2 MinGW GCC. Exact details are at the bottom of the question.
I'm trying to compile following minimal piece of code:
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;
}
Here are results for -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)
And here is -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)
Here are the contents of Z:\Lander\LLVM\lib\clang\8.0.0\lib\windows\
where it looks for libraries:
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
This doesn't look right, since the MinGW GCC normally works with .a
libraries, not .lib
.
I tried to manually link various libraries from that directory.
For asan, I managed to get rid of compiler errors, but the asan itself doesn't seem to emit any diagnostics:
# /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
For ubsan, I tried to link against clang_rt.ubsan_standalone-x86_64.lib
, but got more undefined references and several Warning: corrupt .drectve at end of def file
.
I did some research on Warning: corrupt .drectve at end of def file
, and this question suggests that it means I'm linking incompatible MSVC libraries.
What's going on here? How am I supposed to use asan & ubsan?
All commands above were run from MSYS2 terminal, running on Windows 7 x64.
I'm targeting x86_64 and using latest GCC available in MSYS2:
# g++ --version
g++.exe (Rev2, Built by MSYS2 project) 8.3.0
Clang from MSYS2 doesn't seem to have asan & ubsan libraries bundled, so I'm using the official build from 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
I'm using -target x86_64-w64-windows-gnu
because otherwise Clang tries to use a MSVC installation, which I don't have. This specific triplet is what MSYS2 clang reports in reponse to --version
.
ASAN indeed works on Windows.
To avoid errors such as:
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
use /clang64/bin/clang
instead of /mingw64/bin/clang
. Install it with:
pacman -S mingw-w64-clang-x86_64-clang
See https://www.msys2.org/docs/environments/
I've found a way to make UBsan work, but not Asan.
Turns out, UBsan can function even without libubsan. You need to use following flags:
-fsanitize=undefined -fsanitize-undefined-trap-on-error
This way, errors are reported via crashing with 'Illegal instruction' rather by emitting pretty diagnostics, but it's better than nothing.
This flag is supported by both GCC and Clang.
GCC manual:
-fsanitize-undefined-trap-on-error
The
-fsanitize-undefined-trap-on-error
option instructs the compiler to report undefined behavior using__builtin_trap
rather than a libubsan library routine. The advantage of this is that the libubsan library is not needed and is not linked in, so this is usable even in freestanding environments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With