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, alloca
i 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=address
jest zgodny ze wszystkimi istniejącymi poziomami optymalizacji języka C++ lub C (na przykład /Od
, , /O1
/O2
, i /O2 /GL
). 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ń. Ta opcja kompilatora nie jest obsługiwana w przypadku optymalizacji z przewodnikiem profilu.
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:
- Punkty instrumentacji krawędzi (
/fsanitize-coverage=edge
), - wbudowane liczniki 8-bitowe (
/fsanitize-coverage=inline-8bit-counters
), - porównania (
/fsanitize-coverage=trace-cmp
), i - podziały całkowite (
/fsanitize-coverage=trace-div
).
Zalecamy użycie polecenia z /fsanitize=fuzzer
programem /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 main
LLVMFuzzerInitialize
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:
- Skompiluj
/fsanitize-address-use-after-return
przy użyciu opcji . - 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