Referenční informace k jazyku AddressSanitizer, sestavení a ladění
Části v tomto článku popisují specifikaci jazyka AddressSanitizer, možnosti kompilátoru a možnosti linkeru. Popisují také možnosti, které řídí integraci ladicího programu sady Visual Studio specifické pro AddressSanitizer.
Další informace o modulu runtime AddressSanitizer najdete v referenčních informacích k modulu runtime. Obsahuje informace o zachycený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 preprocesoru __SANITIZE_ADDRESS__
je definováno jako 1
při /fsanitize=address
nastavení. Toto makro je užitečné pro pokročilé uživatele k podmíněnému zadání zdrojového kódu 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 __declspec(no_sanitize_address)
lze použít k selektivnímu zakázání sanitizátoru u funkcí, místních proměnných nebo globálních proměnných. To __declspec
má vliv na chování kompilátoru , nikoli 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 kompilátoru /fsanitize=address
instrumentuje odkazy na paměť v kódu, aby zachytil chyby bezpečnosti paměti za běhu. Instrumentační háky se načítají, ukládají, obory alloca
a funkce CRT. Dokáže rozpoznat skryté chyby, jako jsou mimo hranice, použití po volném rozsahu, použití po rozsahu atd. Seznam neexhaustivních chyb zjištěných za běhu najdete v příkladech chyb AddressSanitizer.
/fsanitize=address
je kompatibilní se všemi existujícími úrovněmi optimalizace jazyka C++ nebo C (například /Od
, /O1
, /O2
a /O2 /GL
). Kód vytvořený pomocí této možnosti funguje se statickými a dynamickými crty (například /MD
, /MDd
, /MT
a /MTd
). Tuto možnost kompilátoru lze použít k vytvoření .EXE nebo .DLL cílení na x86 nebo x64. Pro optimální formátování zásobníků volání se vyžadují informace o ladění. Tato možnost kompilátoru není podporována s optimalizací s asistencí profilu.
Příklady kódu, které demonstruje několik druhů detekce chyb, najdete v příkladech chyb AddressSanitizer.
/fsanitize=fuzzer
Možnost kompilátoru (experimentální)
Možnost /fsanitize=fuzzer
kompilátoru přidá LibFuzzer do výchozího seznamu knihoven. Nastaví také následující možnosti pokrytí sanitizátoru:
- Hraniční instrumentační body (
/fsanitize-coverage=edge
), - vložené 8bitové čítače (
/fsanitize-coverage=inline-8bit-counters
), - porovnání (
/fsanitize-coverage=trace-cmp
) a - celočíselná dělení (
/fsanitize-coverage=trace-div
).
Doporučujeme používat s /fsanitize=address
/fsanitize=fuzzer
.
Tyto knihovny se při zadání přidají /fsanitize=fuzzer
do výchozího seznamu 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é funkci vynechají main
. Je vaší zodpovědností definovat main
a volat LLVMFuzzerInitialize
a LLVMFuzzerTestOneInput
kdy tyto knihovny používáte. Pokud chcete použít některou z těchto knihoven, zadejte /NODEFAULTLIB
a explicitně propojte následující knihovnu, která odpovídá vašemu modulu runtime a architektuře:
Možnost modulu runtime | Knihovna no_main knihovny 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 některou z těchto knihoven a nezadáte /NODEFAULTLIB
ji, zobrazí se nevyřešená chyba odkazu na externí symbol.
/fsanitize-address-use-after-return
Možnost kompilátoru (experimentální)
Kompilátor MSVC (na rozdíl od jazyka Clang) ve výchozím nastavení negeneruje kód pro přidělení rámců v haldě za účelem zachycení chyb použití po vrácení. Chcete-li zachytit tyto chyby pomocí AddressSanitizer, musíte:
- Zkompilujte pomocí
/fsanitize-address-use-after-return
možnosti. - Před spuštěním programu spusťte
set ASAN_OPTIONS=detect_stack_use_after_return=1
nastavení možnosti kontroly za běhu.
Tato /fsanitize-address-use-after-return
možnost způsobí, že kompilátor vygeneruje kód tak, aby v haldě používal duální rámec zásobníku, když se místní hodnoty považují za "pořízenou adresu". Tento kód je mnohem pomalejší než jen použití /fsanitize=address
samotného kódu. Další informace a příklad naleznete v tématu Chyba: stack-use-after-return
.
Duální rámec zásobníku v haldě zůstane po návratu z funkce, která ji vytvořila. Představte si příklad, kdy se po návratu použije adresa místního, přiděleného slotu v haldě. Stínové bajty přidružené k rámečku falešné haldy obsahují hodnotu 0xF9. Tato 0xF9 znamená chybu typu stack-use-after-return, když modul runtime hlásí chybu.
Rámce zásobníku se přidělují v haldě a zůstanou po vrácení funkcí. Modul runtime používá uvolňování paměti k asynchronnímu uvolnění těchto falešných objektů v rámci volání po určitém časovém intervalu. Adresy místních počítačů se přenesou na trvalé snímky v haldě. Systém dokáže zjistit, kdy se po definování funkce použijí všechny místní hodnoty. Další informace najdete v algoritmu použití zásobníku po vrácení , jak je dokumentováno společností Google.
Linker
/INFERASANLIBS[:NO]
možnost linkeru
Možnost /fsanitize=address
kompilátoru označí objekty k určení, kterou knihovnu AddressSanitizer chcete propojit se spustitelným souborem. Knihovny mají názvy, které začínají clang_rt.asan*
. Možnost linkeru /INFERASANLIBS
(ve výchozím nastavení) tyto knihovny automaticky propojí z jejich výchozích umístění. Tady jsou vybrané a automaticky propojené knihovny.
Poznámka:
V následující tabulce {arch}
je buď i386
nebo x86_64
.
Tyto knihovny používají konvence jazyka Clang pro názvy architektur. KonvenceMSch x86
x64
i386
x86_64
Odkazují na stejné architektury.
Možnost CRT | Knihovna modulu runtime AddressSanitizer (.lib) | Binární soubor modulu runtime adresy (.dll) |
---|---|---|
/MT nebo /MTd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_static_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MD nebo /MDd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
Možnost linkeru /INFERASANLIBS:NO
zabrání propojení clang_rt.asan*
souboru knihovny z výchozího umístění. Pokud použijete tuto možnost, přidejte cestu knihovny do skriptů sestavení. V opačném případě linker hlásí nevyřešenou chybu externího symbolu.
Předchozí verze
Před verzí Visual Studio 17.7 Preview 3 nepoužíly staticky propojené (/MT
nebo /MTd
) sestavení závislost knihovny DLL. Místo toho byl modul runtime AddressSanitizer staticky propojený s exe uživatele. Projekty DLL by pak načetly exporty z exe uživatele pro přístup k funkcím ASan. Dynamicky propojené projekty (/MD
nebo /MTd
) také používaly různé knihovny a knihovny DLL v závislosti na tom, jestli byl projekt nakonfigurován pro ladění nebo vydání. Další informace o těchto změnách a jejich motivaci naleznete v tématu MSVC Address Sanitizer – One DLL pro všechny konfigurace modulu runtime.
Možnost modulu runtime CRT | KNIHOVNA 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 |
Kteroukoli | 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 |
Kteroukoli | clang_rt.asan_dbg_dynamic-{arch} , clang_rt.asan_dbg_dynamic_runtime_thunk-{arch} |
Integrace se sadou Visual Studio
/fno-sanitize-address-vcasan-lib
Možnost kompilátoru
Odkazy /fsanitize=address
na možnosti v dalších knihovnách pro vylepšené ladění sady Visual Studio při vyvolání výjimky AddressSanitizer. Tyto knihovny se nazývají VCAsan. Knihovny umožňují sadě Visual Studio zobrazit chyby AddressSanitizer ve zdrojovém kódu. Umožňují spustitelnému souboru také generovat výpisy stavu systému při vytvoření zprávy o chybě AddressSanitizer. Další informace naleznete v tématu Visual Studio AddressSanitizer extended functionality library.
Vybraná knihovna závisí na možnostech kompilátoru a je automaticky propojena.
Možnost modulu runtime | Verze VCAsan |
---|---|
/MT |
libvcasan.lib |
/MD |
vcasan.lib |
/MTd |
libvcasand.lib |
/MDd |
vcasand.lib |
Pokud ale zkompilujete ( /Zl
vynecháte výchozí název knihovny), musíte knihovnu zadat ručně. Pokud to neuděláte, zobrazí se chyba propojení s nevyřešeným externím symbolem. Zde je uvedeno 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 v době kompilace zakázat pomocí této /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ý za běhu zveřejňuje chyby zabezpečení paměti. Při spuštění binárního souboru z příkazového řádku a modul runtime hlásí chybu, vytiskne podrobnosti o chybě. Potom proces ukončí. ASAN_VCASAN_DEBUGGING
Proměnnou prostředí lze nastavit tak, aby se integrované vývojové prostředí sady Visual Studio spustilo 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ůsobil.
Pokud chcete toto chování povolit, spusťte příkaz set ASAN_VCASAN_DEBUGGING=1
před spuštěním aplikace. Rozšířené ladění můžete zakázat spuštěním set ASAN_VCASAN_DEBUGGING=0
příkazu .
Viz také
Přehled AddressSanitizer
Známé problémy s addressSanitizerem
Referenční informace k modulu runtime AddressSanitizer
Stínové bajty AddressSanitizer
AddressSanitizer – cloud nebo distribuované testování
Integrace ladicího programu AddressSanitizer
Příklady chyb AddressSanitizer