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, allocaund 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, /O2und /O2 /GL). Der mit dieser Option erstellte Code funktioniert mit statischen und dynamischen CRTs (z /MD. B. , , /MDd, /MTund /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:

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:

  1. Kompilieren sie mithilfe der /fsanitize-address-use-after-return Option.
  2. 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