Upraviť

Zdieľať cez


AddressSanitizer language, build, and debugging reference

The sections in this article describe the AddressSanitizer language specification, compiler options, and linker options. They also describe the options that control Visual Studio debugger integration specific to the AddressSanitizer.

For more information on the AddressSanitizer runtime, see the runtime reference. It includes information on intercepted functions and how to hook custom allocators. For more information on saving crash dumps from AddressSanitizer failures, see the crash dump reference.

Language specification

__SANITIZE_ADDRESS__

The __SANITIZE_ADDRESS__ preprocessor macro is defined as 1 when /fsanitize=address is set. This macro is useful for advanced users to conditionally specify source code for the presence of the AddressSanitizer runtime.

#include <cstdio>

int main() {
    #ifdef __SANITIZE_ADDRESS__
        printf("Address sanitizer enabled");
    #else
        printf("Address sanitizer not enabled");
    #endif
    return 1;
}

__declspec(no_sanitize_address)

The __declspec(no_sanitize_address) specifier can be used to selectively disable the sanitizer on functions, local variables, or global variables. This __declspec affects compiler behavior, not runtime behavior.

__declspec(no_sanitize_address)
void test1() {
    int x[100];
    x[100] = 5; // ASan exception not caught
}

void test2() {
    __declspec(no_sanitize_address) int x[100];
    x[100] = 5; // ASan exception not caught
}

__declspec(no_sanitize_address) int g[100];
void test3() {
    g[100] = 5; // ASan exception not caught
}

Compiler

/fsanitize=address compiler option

The /fsanitize=address compiler option instruments memory references in your code to catch memory safety errors at runtime. The instrumentation hooks loads, stores, scopes, alloca, and CRT functions. It can detect hidden bugs such as out-of-bounds, use-after-free, use-after-scope, and so on. For a nonexhaustive list of errors detected at runtime, see AddressSanitizer error examples.

/fsanitize=address is compatible with all existing C++ or C optimization levels (for example, /Od, /O1, /O2, and /O2 /GL). The code produced with this option works with static and dynamic CRTs (for example, /MD, /MDd, /MT, and /MTd). This compiler option can be used to create an .EXE or .DLL targeting x86 or x64. Debug information is required for optimal formatting of call stacks. This compiler option is not supported with profile guided optimization.

For examples of code that demonstrates several kinds of error detection, see AddressSanitizer error examples.

/fsanitize=fuzzer compiler option (experimental)

The /fsanitize=fuzzer compiler option adds LibFuzzer to the default library list. It also sets the following sanitizer coverage options:

We recommend you use /fsanitize=address with /fsanitize=fuzzer.

These libraries are added to the default library list when you specify /fsanitize=fuzzer:

Runtime option LibFuzzer library
/MT clang_rt.fuzzer_MT-{arch}
/MD clang_rt.fuzzer_MD-{arch}
/MTd clang_rt.fuzzer_MTd-{arch}
/MDd clang_rt.fuzzer_MDd-{arch}

LibFuzzer libraries that omit the main function are also available. It's your responsibility to define main and to call LLVMFuzzerInitialize and LLVMFuzzerTestOneInput when you use these libraries. To use one of these libraries, specify /NODEFAULTLIB and explicitly link with the following library that corresponds to your runtime and architecture:

Runtime option LibFuzzer no_main library
/MT clang_rt.fuzzer_no_main_MT-{arch}
/MD clang_rt.fuzzer_no_main_MD-{arch}
/MTd clang_rt.fuzzer_no_main_MTd-{arch}
/MDd clang_rt.fuzzer_no_main_MDd-{arch}

If you specify /NODEFAULTLIB and you don't specify one of these libraries, you'll get an unresolved external symbol link error.

/fsanitize-address-use-after-return compiler option (experimental)

By default, the MSVC compiler (unlike Clang) doesn't generate code to allocate frames in the heap to catch use-after-return errors. To catch these errors using AddressSanitizer, you must:

  1. Compile using the /fsanitize-address-use-after-return option.
  2. Before executing your program, run set ASAN_OPTIONS=detect_stack_use_after_return=1 to set the runtime check option.

The /fsanitize-address-use-after-return option causes the compiler to generate code to use a dual stack frame in the heap when locals are considered "address taken." This code is much slower than just using /fsanitize=address alone. For more information and an example, see Error: stack-use-after-return.

The dual stack frame in the heap remains after the return from the function that created it. Consider an example where the address of a local, allocated to a slot in the heap, is used after the return. The shadow bytes associated with the fake heap frame contain the value 0xF9. That 0xF9 means a stack-use-after-return error when the runtime reports the error.

Stack frames are allocated in the heap and remain after functions return. The runtime uses garbage collection to asynchronously free these fake call-frame objects, after a certain time interval. Addresses of locals get transferred to persistent frames in the heap. It's how the system can detect when any locals get used after the defining function returns. For more information, see the algorithm for stack use after return as documented by Google.

Linker

/INFERASANLIBS[:NO] linker option

The /fsanitize=address compiler option marks objects to specify which AddressSanitizer library to link into your executable. The libraries have names that begin with clang_rt.asan*. The /INFERASANLIBS linker option (on by default) links these libraries from their default locations automatically. Here are the libraries chosen and automatically linked in.

Note

In the following table, {arch} is either i386 or x86_64. These libraries use Clang conventions for architecture names. MSVC conventions are normally x86 and x64 rather than i386 and x86_64. They refer to the same architectures.

CRT option AddressSanitizer runtime library (.lib) Address runtime binary (.dll)
/MT or /MTd clang_rt.asan_dynamic-{arch}, clang_rt.asan_static_runtime_thunk-{arch} clang_rt.asan_dynamic-{arch}
/MD or /MDd clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch} clang_rt.asan_dynamic-{arch}

The linker option /INFERASANLIBS:NO prevents the linker from linking a clang_rt.asan* library file from the default location. Add the library path in your build scripts if you use this option. Otherwise, the linker reports an unresolved external symbol error.

Previous Versions

Prior to Visual Studio 17.7 Preview 3, statically linked (/MT or /MTd) builds didn't use a DLL dependency. Instead, the AddressSanitizer runtime was statically linked into the user's EXE. DLL projects would then load exports from the user's EXE to access ASan functionality. Also, dynamically linked projects (/MD or /MTd) used different libraries and DLLs depending on whether the project was configured for debug or release. For more information about these changes and their motivations, see MSVC Address Sanitizer – One DLL for all Runtime Configurations.

CRT runtime option DLL or EXE AddressSanitizer runtime libraries
/MT EXE clang_rt.asan-{arch}, clang_rt.asan_cxx-{arch}
/MT DLL clang_rt.asan_dll_thunk-{arch}
/MD Either clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch}
/MTd EXE clang_rt.asan_dbg-{arch}, clang_rt.asan_dbg_cxx-{arch}
/MTd DLL clang_rt.asan_dbg_dll_thunk-{arch}
/MDd Either clang_rt.asan_dbg_dynamic-{arch}, clang_rt.asan_dbg_dynamic_runtime_thunk-{arch}

Visual Studio integration

/fno-sanitize-address-vcasan-lib compiler option

The /fsanitize=address option links in extra libraries for an improved Visual Studio debugging experience when an AddressSanitizer exception is thrown. These libraries are called VCAsan. The libraries enable Visual Studio to display AddressSanitizer errors on your source code. They also enable the executable to generate crash dumps when an AddressSanitizer error report is created. For more information, see Visual Studio AddressSanitizer extended functionality library.

The library chosen depends on the compiler options, and is automatically linked in.

Runtime option VCAsan version
/MT libvcasan.lib
/MD vcasan.lib
/MTd libvcasand.lib
/MDd vcasand.lib

However, if you compile using /Zl (Omit default library name), you must manually specify the library. If you don't, you'll get an unresolved external symbol link error. Here are some typical examples:

error LNK2001: unresolved external symbol __you_must_link_with_VCAsan_lib
error LNK2001: unresolved external symbol ___you_must_link_with_VCAsan_lib

The improved debugging can be disabled at compile time by using the /fno-sanitize-address-vcasan-lib option.

ASAN_VCASAN_DEBUGGING environment variable

The /fsanitize=address compiler option produces a binary that exposes memory safety bugs at runtime. When the binary is started from the command line, and the runtime reports an error, it prints the error details. It then exits the process. The ASAN_VCASAN_DEBUGGING environment variable can be set to launch the Visual Studio IDE immediately when the runtime reports an error. This compiler option lets you view the error, superimposed over your source code, at the precise line and column that caused the error.

To enable this behavior, run the command set ASAN_VCASAN_DEBUGGING=1 before you run your application. You can disable the enhanced debugging experience by running set ASAN_VCASAN_DEBUGGING=0.

See also

AddressSanitizer overview
AddressSanitizer known issues
AddressSanitizer runtime reference
AddressSanitizer shadow bytes
AddressSanitizer cloud or distributed testing
AddressSanitizer debugger integration
AddressSanitizer error examples