Referenční informace k jazyku AddressSanitizer, sestavení a ladění
Oddíly v tomto článku popisují specifikaci jazyka AddressSanitizer, možnosti kompilátoru a možnosti linkeru. Popisují také možnosti, které řídí integraci Visual Studio ladicího programu, která je specifická pro AddressSanitizer.
Další informace o modulu runtime AddressSanitizer najdete v referenčních informacích k modulu runtime. Obsahuje informace o zachycovaných funkcích a o tom, jak připojit vlastní alokátory. Další informace o ukládání výpisů stavu systému ze selhání AddressSanitizer najdete v referenčních informacích k výpisu stavu systému.
Specifikace jazyka
__SANITIZE_ADDRESS__
Makro __SANITIZE_ADDRESS__ preprocesoru je 1 definováno, jako když je /fsanitize=address nastaveno. Toto makro je užitečné pro pokročilé uživatele, kteří mohou podmíněně určit zdrojový kód pro přítomnost modulu runtime 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)
Specifikátor lze použít k selektivnímu zakázání sanitizéru u funkcí, místních proměnných __declspec(no_sanitize_address) nebo globálních proměnných. To __declspec má vliv na __declspec kompilátoru, nikoli na chování modulu runtime.
__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 možnost kompilátoru
Možnost /fsanitize=address kompilátoru používá v kódu odkazy na paměť, aby zachytály chyby zabezpečení paměti za běhu. Instrumentace zachytí funkce načtení, uložení, oborů alloca a CRT. Dokáže detekovat skryté chyby, jako jsou mimo hranice, použití po bezplatném použití, použití po oboru a tak dále. Úplný seznam chyb zjištěných za běhu najdete v tématu Příklady chyb AddressSanitizer.
/fsanitize=address je kompatibilní se všemi existujícími úrovněmi optimalizace C++ nebo C (například , , , a optimalizace na /Od/O1 základě /O2/O2 /GL profilu). Kód vytvořený pomocí této možnosti funguje se statickými a dynamickými crty (například /MD , /MDd , a /MT/MTd ). Tuto možnost kompilátoru lze použít k vytvoření .EXE nebo .DLL cílení na x86 nebo x64. Informace o ladění jsou vyžadovány pro optimální formátování zásobníků volání.
Příklady kódu, který ukazuje několik druhů detekce chyb, najdete v tématu Příklady chyb AddressSanitizer.
/fsanitize=fuzzer možnost kompilátoru (experimentální)
Možnost /fsanitize=fuzzer kompilátoru přidá /fsanitize=fuzzer do výchozího seznamu knihoven. Nastaví se také následující možnosti pokrytí sanitizérem:
- Hraniční instrumentační body ( ),
- vložené 8bitové čítače ( ),
- comparisons ( ), and
- celočíselné dělení ( ).
Doporučujeme používat s /fsanitize=address/fsanitize=fuzzer .
Tyto knihovny se při zadání přidávají do výchozího seznamu /fsanitize=fuzzer knihoven:
| Možnost modulu runtime | Knihovna 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} |
K dispozici jsou také knihovny LibFuzzer, které main funkci vymění. Je vaší zodpovědností definovat a volat a mainLLVMFuzzerInitialize při používání těchto LLVMFuzzerTestOneInput knihoven. Pokud chcete použít jednu z těchto knihoven, zadejte knihovnu a explicitně ji propoojte s knihovnou, která odpovídá vašemu modulu runtime a /NODEFAULTLIB architektuře:
| Možnost modulu runtime | Knihovna 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} |
Pokud zadáte a nezadáte jednu z těchto knihoven, zobrazí se nerozpoznaná chyba odkazu na /NODEFAULTLIB externí symbol.
/fsanitize-address-use-after-return možnost kompilátoru (experimentální)
Ve výchozím nastavení MSVC kompilátor kódu (na rozdíl od jazyka Clang) negeneruje kód pro přidělení rámců v haldě zachycovat chyby po vrácení. Pokud chcete tyto chyby zachytit pomocí nástroje AddressSanitizer, musíte:
- Zkompilujte pomocí
/fsanitize-address-use-after-returnmožnosti . - Před spuštěním programu spusťte příkaz a
set ASAN_OPTIONS=detect_stack_use_after_return=1nastavte možnost kontroly modulu runtime.
Možnost způsobí, že kompilátor vygeneruje kód tak, aby v haldě používá duální rámec zásobníku, pokud se místní hodnoty považují /fsanitize-address-use-after-return za "zachycené adresy". Tento kód je mnohem pomalejší než použití samotného kódu. Další informace a příklad najdete v tématu Chyba: .
Duální rámec zásobníku v haldě zůstane po návratu z funkce, která ho vytvořila. Představte si příklad, kdy se po vrácení použije adresa místního prostředí přiděleného slotu v haldě. Stínové bajty přidružené k rámu falešné haldy obsahují hodnotu 0xF9. To 0xF9, že když modul runtime hlásí chybu, znamená to chybu stack-use-after-return.
Rámce zásobníku se přidělují v haldě a zůstávají po vrácení funkcí. Modul runtime po uplynutí určitého časového intervalu používá uvolňování paměti k asynchronnímu uvolnění těchto objektů fake call-frame. Adresy místních ip adres se přenesou do trvalých snímků v haldě. Systém tak může zjistit, kdy se po návratu definující funkce používají místní hodnoty. Další informace najdete v tématu Algoritmus pro použití zásobníku po vrácení, jak je zdokumentované společností Google.
Linker
/INFERASANLIBS[:NO] možnost linkeru
Možnost /fsanitize=address kompilátoru označuje objekty, které určují knihovnu AddressSanitizer pro propojení se spustitelným souborem. Knihovny mají názvy, které začínají clang_rt.asan* na . Možnost linkeru (ve výchozím nastavení) propojuje tyto knihovny /INFERASANLIBS z jejich výchozích umístění automaticky. Tady jsou knihovny, které zvolíte a automaticky prodáte:
| Možnost modulu runtime | DLL nebo EXE | Knihovny modulu runtime AddressSanitizer |
|---|---|---|
/MT |
EXE | clang_rt.asan-{arch}, clang_rt.asan_cxx-{arch} |
/MT |
DLL | clang_rt.asan_dll_thunk-{arch} |
/MD |
BUĎ | 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 |
BUĎ | clang_rt.asan_dbg_dynamic-{arch}, clang_rt.asan_dbg_dynamic_runtime_thunk-{arch} |
Možnost /INFERASANLIBS:NO linkeru brání linkeru v propojení souboru knihovny z clang_rt.asan* výchozího umístění. Pokud použijete tuto možnost, přidejte do skriptů sestavení cestu ke knihovně. V opačném případě linker hlásí nevyřešenou chybu externího symbolu.
integrace sady Visual Studio
/fno-sanitize-address-vcasan-lib možnost kompilátoru
Možnosti odkazované v dalších knihovnách pro vylepšené ladění Visual Studio při vyvolání výjimky /fsanitize=address AddressSanitizer. Tyto knihovny se nazývají VCAsan. Knihovny umožňují Visual Studio chyby AddressSanitizer ve zdrojovém kódu. Umožňují také spustitelnému souboru generovat výpisy stavu systému při vytvoření sestavy chyb AddressSanitizer. Další informace najdete v tématu Visual Studio s rozšířenými funkcemi AddressSanitizer.
Zvolená knihovna závisí na možnostech kompilátoru a je automaticky propojena v .
| Možnost modulu runtime | Verze VCAsan |
|---|---|
/MT |
libvcasan.lib |
/MD |
vcasan.lib |
/MTd |
libvcasand.lib |
/MDd |
vcasand.lib |
Pokud ale kompilaci používáte (vynechat výchozí název knihovny), budete muset knihovnu /Zl zadat ručně. Pokud ne, zobrazí se chyba odkazu na nevyřešený externí symbol. Tady je několik typických příkladů:
error LNK2001: unresolved external symbol __you_must_link_with_VCAsan_lib
error LNK2001: unresolved external symbol ___you_must_link_with_VCAsan_lib
Vylepšené ladění lze zakázat v době kompilace pomocí /fno-sanitize-address-vcasan-lib možnosti .
ASAN_VCASAN_DEBUGGING proměnná prostředí
Možnost /fsanitize=address kompilátoru vytvoří binární soubor, který zveřejňuje chyby zabezpečení paměti za běhu. Když je binární soubor spuštěn z příkazového řádku a modul runtime hlásí chybu, vytiskne podrobnosti o chybě. Pak proces ukončí. Proměnnou ASAN_VCASAN_DEBUGGING prostředí je možné nastavit tak, aby se Visual Studio ideu prostředí okamžitě, když modul runtime hlásí chybu. Tato možnost kompilátoru umožňuje zobrazit chybu nad zdrojovým kódem na přesném řádku a sloupci, které chybu způsobily.
Pokud chcete toto chování povolit, spusťte před set ASAN_VCASAN_DEBUGGING=1 spuštěním aplikace příkaz . Rozšířené možnosti ladění můžete zakázat spuštěním set ASAN_VCASAN_DEBUGGING=0 .
Viz také
Přehled AddressSanitizer
Známé problémy s AddressSanitizerem
Referenční informace k modulu runtime AddressSanitizer
Stínové bajty AddressSanitizer
Cloud AddressSanitizer nebo distribuované testování
Integrace ladicího programu AddressSanitizer
Příklady chyb AddressSanitizer