AddressSanitizer-Sprache, Build- und Debugreferenz
In den Abschnitten in diesem Artikel werden die AddressSanitizer-Sprachspezifikation, Compileroptionen und Linkeroptionen beschrieben. Außerdem werden die Optionen beschrieben, mit denen die für addressSanitizer spezifische Visual Studio-Debuggerintegration gesteuert wird.
Weitere Informationen zur AddressSanitizer-Laufzeit finden Sie in der Laufzeitreferenz. Sie enthält Informationen zu abgefangenen Funktionen und zum Binden von benutzerdefinierten Zuweisungen. Weitere Informationen zum Speichern von Absturzabbildern von AddressSanitizer-Fehlern finden Sie in der Absturzabbildreferenz.
Sprachspezifikation
__SANITIZE_ADDRESS__
Das __SANITIZE_ADDRESS__
Präprozessormakro wird beim 1
/fsanitize=address
Festlegen definiert. Dieses Makro ist nützlich, um erweiterte Benutzer bedingten Quellcode für das Vorhandensein der AddressSanitizer-Laufzeit anzugeben.
#include <cstdio>
int main() {
#ifdef __SANITIZE_ADDRESS__
printf("Address sanitizer enabled");
#else
printf("Address sanitizer not enabled");
#endif
return 1;
}
__declspec(no_sanitize_address)
Der __declspec(no_sanitize_address)
Bezeichner kann zum selektiven Deaktivieren des Bereinigungsprogramms für Funktionen, lokale Variablen oder globale Variablen verwendet werden. Dies __declspec
wirkt sich auf das Compilerverhalten und nicht auf das Laufzeitverhalten aus .
__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
Compileroption
Die /fsanitize=address
Compileroption instrumentiert Speicherverweise in Ihrem Code, um Speichersicherheitsfehler zur Laufzeit abzufangen. Die Instrumentierungshaken laden, speichern, bereiche, alloca
und CRT-Funktionen. Es kann ausgeblendete Fehler wie out-of-bounds, use-after-free, use-after-scope usw. erkennen. Eine nichtexextive Liste der fehler, die zur Laufzeit erkannt wurden, finden Sie unter AddressSanitizer-Fehlerbeispiele.
/fsanitize=address
ist kompatibel mit allen vorhandenen C++- oder C-Optimierungsstufen (z /Od
. B. , , /O1
, /O2
und /O2 /GL
). Der mit dieser Option erstellte Code funktioniert mit statischen und dynamischen CRTs (z /MD
. B. , , /MDd
, /MT
und /MTd
). Diese Compileroption kann verwendet werden, um eine .EXE oder .DLL für x86 oder x64 zu erstellen. Debuginformationen sind für eine optimale Formatierung von Aufrufstapeln erforderlich. Diese Compileroption wird bei der profilgeführten Optimierung nicht unterstützt.
Beispiele für Code, der verschiedene Arten der Fehlererkennung veranschaulicht, finden Sie unter AddressSanitizer-Fehlerbeispiele.
/fsanitize=fuzzer
Compileroption (experimentell)
Die /fsanitize=fuzzer
Compileroption fügt libFuzzer zur Standardbibliotheksliste hinzu. Außerdem werden die folgenden Bereinigungsoptionen festgelegt:
- Randinstrumentationspunkte (
/fsanitize-coverage=edge
), - Inline-8-Bit-Zähler (
/fsanitize-coverage=inline-8bit-counters
), - Vergleiche (
/fsanitize-coverage=trace-cmp
) und - ganze Zahlen (
/fsanitize-coverage=trace-div
).
Wir empfehlen Die Verwendung /fsanitize=address
mit /fsanitize=fuzzer
.
Diese Bibliotheken werden der Standardbibliotheksliste hinzugefügt, wenn Sie Folgendes angeben /fsanitize=fuzzer
:
Runtime-Option | LibFuzzer-Bibliothek |
---|---|
/MT |
clang_rt.fuzzer_MT-{arch} |
/MD |
clang_rt.fuzzer_MD-{arch} |
/MTd |
clang_rt.fuzzer_MTd-{arch} |
/MDd |
clang_rt.fuzzer_MDd-{arch} |
LibFuzzer-Bibliotheken, die die main
Funktion weglassen, sind ebenfalls verfügbar. Es liegt in Ihrer Verantwortung, diese Bibliotheken zu definieren main
und aufzurufen LLVMFuzzerInitialize
und LLVMFuzzerTestOneInput
zu verwenden. Um eine dieser Bibliotheken zu verwenden, geben Sie eine der folgenden Bibliotheken an /NODEFAULTLIB
, und verknüpfen Sie sie explizit mit der folgenden Bibliothek, die Ihrer Laufzeit und Architektur entspricht:
Runtime-Option | Bibliothek "LibFuzzer no_main" |
---|---|
/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} |
Wenn Sie eine dieser Bibliotheken angeben /NODEFAULTLIB
und keine dieser Bibliotheken angeben, erhalten Sie einen Fehler bei einem nicht aufgelösten externen Symbolverknüpfungsfehler.
/fsanitize-address-use-after-return
Compileroption (experimentell)
Standardmäßig generiert der MSVC-Compiler (im Gegensatz zu Clang) keinen Code, um Frames im Heap zuzuordnen, um Verwendungsnachholfehler abzufangen. Um diese Fehler mithilfe von AddressSanitizer abzufangen, müssen Sie:
- Kompilieren sie mithilfe der
/fsanitize-address-use-after-return
Option. - Führen Sie vor dem Ausführen des Programms aus
set ASAN_OPTIONS=detect_stack_use_after_return=1
, um die Laufzeitüberprüfungsoption festzulegen.
Die /fsanitize-address-use-after-return
Option bewirkt, dass der Compiler Code generiert, um einen dualen Stapelframe im Heap zu verwenden, wenn Lokale als "Adresse verwendet" betrachtet werden. Dieser Code ist viel langsamer als allein zu verwenden /fsanitize=address
. Weitere Informationen und ein Beispiel finden Sie unter Fehler: stack-use-after-return
.
Der duale Stapelrahmen im Heap verbleibt nach der Rückgabe der Funktion, die ihn erstellt hat. Betrachten Sie ein Beispiel, in dem die Adresse eines lokalen Elements, das einem Steckplatz im Heap zugeordnet ist, nach der Rückgabe verwendet wird. Die Schattenbytes, die dem gefälschten Heapframe zugeordnet sind, enthalten den Wert 0xF9. Dies 0xF9 bedeutet einen Stack-use-after-return-Fehler, wenn die Laufzeit den Fehler meldet.
Stapelframes werden im Heap zugewiesen und bleiben nach der Rückgabe von Funktionen erhalten. Die Laufzeit verwendet die Garbage Collection, um diese gefälschten Aufrufframeobjekte nach einem bestimmten Zeitintervall asynchron frei zu geben. Adressen von Lokalen werden in beständigen Frames im Heap übertragen. So kann das System erkennen, wann lokale Elemente verwendet werden, nachdem die definierende Funktion zurückgegeben wurde. Weitere Informationen finden Sie im Algorithmus für die Stapelverwendung nach der Rückgabe von Google.
Linker
/INFERASANLIBS[:NO]
Linkeroption
Die /fsanitize=address
Compileroption markiert Objekte, um anzugeben, welche AddressSanitizer-Bibliothek mit Ihrer ausführbaren Datei verknüpft werden soll. Die Bibliotheken weisen Namen auf, die mit clang_rt.asan*
. Die /INFERASANLIBS
Linkeroption (standardmäßig aktiviert) verknüpft diese Bibliotheken automatisch von ihren Standardspeicherorten. Hier sind die ausgewählten und automatisch verknüpften Bibliotheken.
Hinweis
In der folgenden Tabelle {arch}
ist entweder i386
oder x86_64
.
Diese Bibliotheken verwenden Clang-Konventionen für Architekturnamen. MSVC-Konventionen sind normalerweise x86
und x64
nicht und nicht i386
.x86_64
Sie beziehen sich auf die gleichen Architekturen.
CRT-Option | AddressSanitizer-Laufzeitbibliothek (.lib) | Adresslaufzeit-Binärdatei (.dll) |
---|---|---|
/MT oder /MTd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_static_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MD oder /MDd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
Die Linkeroption /INFERASANLIBS:NO
verhindert, dass der Linker eine clang_rt.asan*
Bibliotheksdatei vom Standardspeicherort verknüpft. Fügen Sie den Bibliothekspfad in Ihren Buildskripts hinzu, wenn Sie diese Option verwenden. Andernfalls meldet der Linker einen nicht aufgelösten externen Symbolfehler.
Vorgängerversionen
Vor Visual Studio 17.7 Preview 3 wurden statisch verknüpfte (/MT
oder /MTd
) Builds keine DLL-Abhängigkeit verwendet. Stattdessen wurde die AddressSanitizer-Laufzeit statisch mit der EXE des Benutzers verknüpft. DLL-Projekte würden dann Exporte aus der EXE des Benutzers laden, um auf die ASan-Funktionalität zuzugreifen. Außerdem haben dynamisch verknüpfte Projekte (/MD
oder /MTd
) unterschiedliche Bibliotheken und DLLs verwendet, je nachdem, ob das Projekt für das Debuggen oder Freigeben konfiguriert wurde. Weitere Informationen zu diesen Änderungen und ihren Motivationen finden Sie unter MSVC Address Sanitizer – Eine DLL für alle Laufzeitkonfigurationen.
CRT-Laufzeitoption | DLL oder EXE | AddressSanitizer-Laufzeitbibliotheken |
---|---|---|
/MT |
EXE | clang_rt.asan-{arch} , clang_rt.asan_cxx-{arch} |
/MT |
DLL | clang_rt.asan_dll_thunk-{arch} |
/MD |
Sowohl als auch | 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 |
Sowohl als auch | clang_rt.asan_dbg_dynamic-{arch} , clang_rt.asan_dbg_dynamic_runtime_thunk-{arch} |
Integration von Visual Studio
/fno-sanitize-address-vcasan-lib
Compileroption
Die /fsanitize=address
Optionslinks in zusätzlichen Bibliotheken für eine verbesserte Visual Studio-Debugerfahrung, wenn eine AddressSanitizer-Ausnahme ausgelöst wird. Diese Bibliotheken werden VCAsan genannt. Die Bibliotheken ermöglichen Visual Studio das Anzeigen von AddressSanitizer-Fehlern in Ihrem Quellcode. Sie ermöglichen außerdem, dass die ausführbare Datei Absturzabbilder generiert, wenn ein AddressSanitizer-Fehlerbericht erstellt wird. Weitere Informationen finden Sie in der Erweiterten Funktionalitätsbibliothek von Visual Studio AddressSanitizer.
Die ausgewählte Bibliothek hängt von den Compileroptionen ab und wird automatisch verknüpft.
Runtime-Option | VCAsan-Version |
---|---|
/MT |
libvcasan.lib |
/MD |
vcasan.lib |
/MTd |
libvcasand.lib |
/MDd |
vcasand.lib |
Wenn Sie jedoch kompilieren /Zl
(Standardbibliotheksname weglassen), müssen Sie die Bibliothek manuell angeben. Wenn dies nicht der Fehler ist, erhalten Sie einen fehler bei der Verknüpfung mit nicht aufgelösten externen Symbolen. Im Folgenden finden Sie einige typische Beispiele:.
error LNK2001: unresolved external symbol __you_must_link_with_VCAsan_lib
error LNK2001: unresolved external symbol ___you_must_link_with_VCAsan_lib
Das verbesserte Debuggen kann zur Kompilierungszeit mithilfe der /fno-sanitize-address-vcasan-lib
Option deaktiviert werden.
Umgebungsvariable ASAN_VCASAN_DEBUGGING
Die /fsanitize=address
Compileroption erzeugt eine Binärdatei, die Speichersicherheitsfehler zur Laufzeit verfügbar macht. Wenn die Binärdatei über die Befehlszeile gestartet wird und die Laufzeit einen Fehler meldet, werden die Fehlerdetails ausgegeben. Anschließend wird der Prozess beendet. Die ASAN_VCASAN_DEBUGGING
Umgebungsvariable kann so festgelegt werden, dass die Visual Studio-IDE sofort gestartet wird, wenn die Laufzeit einen Fehler meldet. Mit dieser Compileroption können Sie den Fehler in der genauen Zeile und Spalte anzeigen, die den Fehler verursacht hat.
Um dieses Verhalten zu aktivieren, führen Sie den Befehl set ASAN_VCASAN_DEBUGGING=1
aus, bevor Sie die Anwendung ausführen. Sie können die erweiterte Debugerfahrung deaktivieren, indem Sie diese ausführen set ASAN_VCASAN_DEBUGGING=0
.
Siehe auch
AddressSanitizer -Übersicht
Beheben bekannter Probleme mit demSanitizer
AddressSanitizer-Laufzeitreferenz
AddressSanitizer-Schattenbytes
AddressSanitizer-Cloud oder verteilte Tests
AddressSanitizer Debugger-Integration
Beispiele für AddressSanitizer-Fehler