在 MSVC 中,如果我在打开地址清理程序的情况下执行此操作,则会出现运行时异常:
#include <vector>
int main()
{
std::vector<int> my_vector;
my_vector.reserve(20);
my_vector.assign({ 1, 1, 1 });
int* p = my_vector.data();
std::cout << p[3];
/*ERROR: AddressSanitizer: container-overflow on address 0x11d4a44ebf1c at pc 0x7ff6a882ae53 bp 0x0020d85cf720 sp 0x0020d85cf728
READ of size 4 at 0x11d4a44ebf1c thread T0*/
}
HINT: if you don't care about these errors you may set ASAN_OPTIONS=detect_container_overflow=0.
If you suspect a false positive see also: https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow.
我花了一段时间才弄清楚这个命令应该放在“调试”菜单下的环境变量中。我不明白的是,ASAN 不仅仅是一个调试工具。例如,我可以在打开消毒剂的情况下以发布模式运行它,为什么必须将 ASAN_OPTIONS=detect_container_overflow=0 作为调试环境变量传递?起初我认为它应该传递给编译器选项或作为预处理器定义或其他东西。
有没有办法在 CMake 中设置它?我试过:
set(ENV{ASAN_OPTIONS} "detect_container_overflow=0")
我的CMake:
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
message("Using GCC compiler")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
message("Using Clang compiler")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
message("Using MSVC compiler")
add_compile_options(
/MP # MULTIPROCESSOR COMPILE
/Oi # ENABLE COMPILER INTRINSICS
/utf-8
$<$<CONFIG:DEBUG>:/fsanitize=address>
$<$<CONFIG:DEBUG>:/fsanitize=fuzzer>
)
set(ENV{ASAN_OPTIONS} "detect_container_overflow=0") # SET THIS BECAUSE SHADERC THROWS A FALSE POSITIVE ERROR BECAUSE THE LIBRARY WASN'T COMPILED WITH SANITIZER ON
else ()
message("Unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
endif ()
这对 ASAN 标志没有影响,因此它不会进入正确的位置。
环境变量会继承给子进程 - 如果您在
cmake
中设置环境变量,编译器会看到它,因为编译器是从 cmake
进程运行的。
但是,您不是从
.exe
内部运行 cmake
,因此您在 cmake
中设置的任何环境变量都不会影响您的 .exe
。
如果您从
.exe
窗口运行 cmd
,您应该能够在运行程序之前执行类似 set ASAN_OPTIONS=detect_container_overflow=0
的操作。除此之外,您可以在系统属性中设置它 - 但这会影响您正在运行的所有程序(尽管我认为其中没有很多内置 ASAN)。