AddressSanitizer language, build, and debug reference (Język, kompilacja i debugowanie)

W sekcjach w tym artykule opisano specyfikację języka AddressSanitizer, opcje kompilatora i opcje konsolidatora. Opisują również opcje kontrolujące integrację debugera programu Visual Studio specyficzne dla narzędzia AddressSanitizer.

Aby uzyskać więcej informacji na temat środowiska uruchomieniowego AddressSanitizer, zobacz dokumentację środowiska uruchomieniowego. Zawiera informacje na temat przechwyconych funkcji i sposobu podłączania niestandardowych alokatorów. Aby uzyskać więcej informacji na temat zapisywania zrzutów awaryjnych z błędów AddressSanitizer, zobacz dokumentację zrzutu awaryjnego.

Specyfikacja języka

__SANITIZE_ADDRESS__

__SANITIZE_ADDRESS__ Makro preprocesora jest definiowane tak, jak 1 w przypadku /fsanitize=address ustawienia. To makro jest przydatne dla zaawansowanych użytkowników w celu warunkowego określenia kodu źródłowego dla obecności środowiska uruchomieniowego AddressSanitizer.

#include <cstdio>

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

__declspec(no_sanitize_address)

Specyfikator __declspec(no_sanitize_address) może służyć do selektywnego wyłączania oczyszczania funkcji, zmiennych lokalnych lub zmiennych globalnych. Ma to __declspec wpływ na zachowanie kompilatora, a nie zachowanie środowiska uruchomieniowego.

__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 Opcja kompilatora

Kompilator /fsanitize=address opcji instrumentuje odwołania do pamięci w kodzie w celu przechwycenia błędów bezpieczeństwa pamięci w czasie wykonywania. Instrumentacja ładuje, przechowuje, zakresy, allocai funkcje CRT. Może wykrywać ukryte usterki, takie jak poza granicami, bez użycia, zakres użycia i tak dalej. Aby uzyskać niewyczerpaną listę błędów wykrytych w czasie wykonywania, zobacz AddressSanitizer error examples (Przykłady błędów AddressSanitizer).

/fsanitize=addressjest zgodny ze wszystkimi istniejącymi poziomami optymalizacji języka C++ lub C (na przykład /Od, , /O1/O2, , /O2 /GLi optymalizacji z przewodnikiem profilu). Kod utworzony za pomocą tej opcji działa ze statycznymi i dynamicznymi kodami CTT (na przykład /MD, , /MDd/MT, i /MTd). Tej opcji kompilatora można użyć do utworzenia .EXE lub .DLL określania wartości docelowej x86 lub x64. Informacje debugowania są wymagane do optymalnego formatowania stosów wywołań.

Przykłady kodu, który demonstruje kilka rodzajów wykrywania błędów, zobacz AddressSanitizer error examples (Przykłady błędów AddressSanitizer).

/fsanitize=fuzzer Opcja kompilatora (eksperymentalna)

Opcja kompilatora /fsanitize=fuzzer dodaje bibliotekę LibFuzzer do domyślnej listy bibliotek. Ustawia również następujące opcje pokrycia sanitizer:

Zalecamy użycie polecenia z /fsanitize=fuzzerprogramem /fsanitize=address .

Te biblioteki są dodawane do domyślnej listy bibliotek po określeniu elementu /fsanitize=fuzzer:

Opcja środowiska uruchomieniowego Biblioteka LibFuzzer
/MT clang_rt.fuzzer_MT-{arch}
/MD clang_rt.fuzzer_MD-{arch}
/MTd clang_rt.fuzzer_MTd-{arch}
/MDd clang_rt.fuzzer_MDd-{arch}

Biblioteki LibFuzzer pomijające main funkcję są również dostępne. Twoim zadaniem jest zdefiniowanie i wywołanie mainLLVMFuzzerInitialize bibliotek oraz LLVMFuzzerTestOneInput użycie tych bibliotek. Aby użyć jednej z tych bibliotek, określ /NODEFAULTLIB i jawnie połącz z następującą biblioteką odpowiadającą środowisku uruchomieniowemu i architekturze:

Opcja środowiska uruchomieniowego Biblioteka no_main LibFuzzer
/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}

Jeśli określisz /NODEFAULTLIB i nie określisz jednej z tych bibliotek, zostanie wyświetlony nierozwiązany błąd linku symbolu zewnętrznego.

/fsanitize-address-use-after-return Opcja kompilatora (eksperymentalna)

Domyślnie kompilator MSVC (w przeciwieństwie do języka Clang) nie generuje kodu w celu przydzielenia ramek w stercie w celu przechwycenia błędów użycia po powrocie. Aby przechwycić te błędy przy użyciu narzędzia AddressSanitizer, musisz:

  1. Skompiluj /fsanitize-address-use-after-return przy użyciu opcji .
  2. Przed wykonaniem programu uruchom polecenie set ASAN_OPTIONS=detect_stack_use_after_return=1 , aby ustawić opcję sprawdzania środowiska uruchomieniowego.

Opcja /fsanitize-address-use-after-return powoduje, że kompilator generuje kod w celu użycia podwójnej ramki stosu w stercie, gdy ustawienia lokalne są uznawane za "adres podjęte". Ten kod jest znacznie wolniejszy niż tylko używanie samego kodu /fsanitize=address . Aby uzyskać więcej informacji i przykład, zobacz Błąd: stack-use-after-return.

Ramka podwójnego stosu w stercie pozostaje po powrocie z funkcji, która ją utworzyła. Rozważmy przykład, w którym adres lokalnego przydzielonego do gniazda w stercie jest używany po powrocie. Bajty cieni skojarzone z fałszywą ramką sterty zawierają wartość 0xF9. To 0xF9 oznacza błąd stack-use-after-return, gdy środowisko uruchomieniowe zgłasza błąd.

Ramki stosu są przydzielane na stercie i pozostają po powrocie funkcji. Środowisko uruchomieniowe używa odzyskiwania pamięci, aby asynchronicznie zwolnić te fałszywe obiekty ramki wywołań po pewnym przedziale czasu. Adresy mieszkańców są przenoszone do trwałych ramek w stercie. W ten sposób system może wykrywać, kiedy wszystkie lokalne są używane po powrocie funkcji definiującej. Aby uzyskać więcej informacji, zobacz algorytm użycia stosu po powrocie zgodnie z dokumentacją firmy Google.

Konsolidator

/INFERASANLIBS[:NO] opcja konsolidatora

Opcja /fsanitize=address kompilatora oznacza obiekty, aby określić, która biblioteka AddressSanitizer ma być łączony do pliku wykonywalnego. Biblioteki mają nazwy rozpoczynające się od clang_rt.asan*. Opcja konsolidatora (domyślnie włączona /INFERASANLIBS ) łączy te biblioteki z domyślnych lokalizacji automatycznie. Poniżej przedstawiono biblioteki wybrane i automatycznie połączone.

Uwaga

W poniższej tabeli {arch} znajduje się wartość i386 lub x86_64. Te biblioteki używają konwencji języka Clang dla nazw architektury. Konwencje MSVC są zwykle x86 i x64 zamiast i386 i x86_64. Odnoszą się one do tych samych architektur.

Opcja CRT Biblioteka środowiska uruchomieniowego AddressSanitizer (.lib) Plik binarny środowiska uruchomieniowego adresu (.dll)
/MT lub /MTd clang_rt.asan_dynamic-{arch}, clang_rt.asan_static_runtime_thunk-{arch} clang_rt.asan_dynamic-{arch}
/MD lub /MDd clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch} clang_rt.asan_dynamic-{arch}

Opcja /INFERASANLIBS:NO konsolidatora uniemożliwia konsolidatorowi łączenie clang_rt.asan* pliku biblioteki z lokalizacji domyślnej. Dodaj ścieżkę biblioteki w skryptach kompilacji, jeśli używasz tej opcji. W przeciwnym razie konsolidator zgłasza nierozwiązany błąd symbolu zewnętrznego.

Poprzednie wersje

Przed programem Visual Studio 17.7 (wersja zapoznawcza 3) kompilacje statycznie połączone (/MT lub /MTd) nie używały zależności biblioteki DLL. Zamiast tego środowisko uruchomieniowe AddressSanitizer zostało statycznie połączone z plikiem EXE użytkownika. Następnie projekty DLL ładują eksporty z pliku EXE użytkownika w celu uzyskania dostępu do funkcji ASan. Ponadto dynamicznie połączone projekty (/MD lub /MTd) używały różnych bibliotek i bibliotek DLL w zależności od tego, czy projekt został skonfigurowany do debugowania, czy wydania. Aby uzyskać więcej informacji na temat tych zmian i ich motywacji, zobacz MSVC Address Sanitizer — jedna biblioteka DLL dla wszystkich konfiguracji środowiska uruchomieniowego.

Opcja środowiska uruchomieniowego CRT BIBLIOTEKA DLL lub EXE Biblioteki środowiska uruchomieniowego AddressSanitizer
/MT EXE clang_rt.asan-{arch}, clang_rt.asan_cxx-{arch}
/MT DLL clang_rt.asan_dll_thunk-{arch}
/MD Dowolny 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 Dowolny clang_rt.asan_dbg_dynamic-{arch}, clang_rt.asan_dbg_dynamic_runtime_thunk-{arch}

Integracja z programem Visual Studio

/fno-sanitize-address-vcasan-lib Opcja kompilatora

Linki /fsanitize=address opcji w dodatkowych bibliotekach dla ulepszonego środowiska debugowania programu Visual Studio po wystąpieniu wyjątku AddressSanitizer. Te biblioteki są nazywane VCAsan. Biblioteki umożliwiają programowi Visual Studio wyświetlanie błędów AddressSanitizer w kodzie źródłowym. Umożliwiają one również plikowi wykonywalne generowanie zrzutów awaryjnych podczas tworzenia raportu o błędach AddressSanitizer. Aby uzyskać więcej informacji, zobacz rozszerzoną bibliotekę funkcji programu Visual Studio AddressSanitizer.

Wybrana biblioteka zależy od opcji kompilatora i jest automatycznie połączona.

Opcja środowiska uruchomieniowego Wersja VCAsan
/MT libvcasan.lib
/MD vcasan.lib
/MTd libvcasand.lib
/MDd vcasand.lib

Jeśli jednak kompilujesz przy użyciu ( /Zl pomiń domyślną nazwę biblioteki), musisz ręcznie określić bibliotekę. Jeśli tego nie zrobisz, zostanie wyświetlony nierozwiązany błąd linku symbolu zewnętrznego. Oto kilka typowych przykładów:

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

Ulepszone debugowanie można wyłączyć w czasie kompilacji przy użyciu /fno-sanitize-address-vcasan-lib opcji .

ASAN_VCASAN_DEBUGGING zmienna środowiskowa

Opcja kompilatora /fsanitize=address tworzy plik binarny, który uwidacznia błędy bezpieczeństwa pamięci w czasie wykonywania. Gdy plik binarny jest uruchamiany z poziomu wiersza polecenia, a środowisko uruchomieniowe zgłasza błąd, wyświetla szczegóły błędu. Następnie kończy proces. Zmienną ASAN_VCASAN_DEBUGGING środowiskową można ustawić tak, aby uruchamiać środowisko IDE programu Visual Studio natychmiast, gdy środowisko uruchomieniowe zgłasza błąd. Ta opcja kompilatora umożliwia wyświetlenie błędu nałożonego na kod źródłowy w dokładnym wierszu i kolumnie, która spowodowała błąd.

Aby włączyć to zachowanie, uruchom polecenie set ASAN_VCASAN_DEBUGGING=1 przed uruchomieniem aplikacji. Możesz wyłączyć ulepszone środowisko debugowania, uruchamiając polecenie set ASAN_VCASAN_DEBUGGING=0.

Zobacz też

AddressSanitizer — omówienie
Rozwiązywanie znanych problemów z programemSanitizer
AddressSanitizer runtime reference (Dokumentacja środowiska uruchomieniowego AddressSanitizer)
Bajty w tle addressSanitizer
AddressSanitizer — chmura lub testowanie rozproszone
Integracja debugera AddressSanitizer
Przykłady błędów addressSanitizer