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:

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:

  1. Zkompilujte pomocí /fsanitize-address-use-after-return možnosti .
  2. Před spuštěním programu spusťte příkaz a set ASAN_OPTIONS=detect_stack_use_after_return=1 nastavte 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