AddressSanitizer

Überblick

Die C & ++-Sprachen sind leistungsfähig, können aber unter einer Klasse von Fehlern leiden, die sich auf die Programmkorrektur und die Programmsicherheit auswirken. Ab Visual Studio 2019 Version 16.9 unterstützt der Microsoft C/C++-Compiler (MSVC) und die IDE den AddressSanitizer. AddressSanitizer (ASan) ist eine Compiler- und Laufzeittechnologie, die viele schwer zu findende Fehler mit null falsch positiven Fehlern verfügbar macht:

Verwenden Sie AddressSanitizer, um Ihre Zeit zu reduzieren:

  • Grundlegende Korrektheit
  • Plattformübergreifende Portierung
  • Sicherheit
  • Belastungstest
  • Integrieren neuer Code

AddressSanitizer, ursprünglich von Google eingeführt, ist eine leistungsstarke Alternative zu beiden /RTC (Runtime-Fehlerüberprüfungen) und /analyze (Statische Analyse). Es bietet Laufzeitfehlersuche-Technologien, die Ihre vorhandenen Buildsysteme und vorhandene Testressourcen direkt verwenden.

AddressSanitizer ist in das Visual Studio-Projektsystem, das CMake-Buildsystem und die IDE integriert. Projekte können AddressSanitizer aktivieren, indem Sie eine Projekteigenschaft festlegen oder eine zusätzliche Compileroption verwenden: /fsanitize=address Die neue Option ist mit allen Optimierungs- und Konfigurationsebenen von x86 und x64 kompatibel. Es ist jedoch nicht kompatibel mit edit-and-continue, inkrementelle Verknüpfung und /RTC.

Ab Visual Studio 2019 Version 16.9 ermöglicht Microsofts AddressSanitizer-Technologie die Integration mit der Visual Studio IDE. Die Funktionalität kann optional eine Absturzabbilddatei erstellen, wenn der Sanitizer einen Fehler zur Laufzeit findet. Wenn Sie die ASAN_SAVE_DUMPS=MyFileName.dmp Umgebungsvariable festlegen, bevor Sie Ihr Programm ausführen, wird eine Absturzabbilddatei mit zusätzlichen Metadaten erstellt, um effizientes Post-Mortem-Debug von genau diagnostizierten Fehlern zu erstellen. Diese Dumpdateien erleichtern die erweiterte Verwendung des AddressSanitizers für:

  • Lokale Computertests,
  • Lokale verteilte Tests und
  • Cloudbasierte Workflows zum Testen.

Installieren des AddressSanitizers

Die AddressSanitizer-IDE-Integration und -Bibliotheken werden standardmäßig mit C++-Workloads im Visual Studio-Installer installiert. Wenn Sie jedoch ein Upgrade von einer älteren Version von Visual Studio 2019 durchführen, verwenden Sie das Installationsprogramm, um den ASan-Support nach dem Upgrade zu aktivieren:

Visual Studio Installer screenshot highlighting the C++ AddressSanitizer component

Sie können auf Ihrer vorhandenen Visual Studio Installation aus dem Visual Studio-Installer auswählen, um zum oben genannten Bildschirm zu gelangen.

Hinweis

Wenn Sie Visual Studio auf dem neuen Update ausführen, aber keine ASan installiert haben, erhalten Sie beim Ausführen des Codes einen Fehler:

LNK1356: Die Bibliothek "clang_rt.asan_dynamic-i386.lib" kann nicht gefunden werden.

Verwenden des AddressSanitizers

Starten Sie das Erstellen Ihrer ausführbaren Dateien mit der /fsanitize=address Compileroption mit einer der folgenden allgemeinen Entwicklungsmethoden:

  • Befehlszeilenbuilds
  • Visual Studio-Projektsystem
  • Visual Studio CMake-Integration

Wiederholen Sie das Kompilieren, und führen Sie das Programm dann normal aus. Diese Codegenerierung stellt viele Arten genau diagnostizierter Fehler zur Verfügung. Diese Fehler werden auf drei Arten gemeldet: in der Debugger-IDE, in der Befehlszeile oder in einem neuen Typ von Dumpdatei für die präzise Off-Line-Verarbeitung gespeichert.

Microsoft empfiehlt die Verwendung des AddressSanitizers in diesen drei Standardworkflows:

In diesem Artikel werden die Informationen behandelt, die Sie benötigen, um die oben aufgeführten drei Workflows zu aktivieren. Die Informationen sind speziell für die plattformabhängige Windows 10 Implementierung des AddressSanitizers. Diese Dokumentation ergänzt die hervorragende Dokumentation von Google, Apple und GCC bereits veröffentlicht.

Hinweis

Die aktuelle Unterstützung ist auf x86 und x64 auf Windows 10 beschränkt. Senden Sie uns Feedback darüber, was Sie in zukünftigen Versionen sehen möchten. Ihr Feedback hilft uns, andere Sanitizer für die Zukunft zu priorisieren, z/fsanitize=thread. B. , /fsanitize=undefined/fsanitize=leak/fsanitize=memoryoder ./fsanitize=hwaddress Sie können hier Fehler melden , wenn Probleme auftreten.

Verwenden des AddressSanitizers aus einer Entwicklerbefehlsaufforderung

Verwenden Sie die /fsanitize=address Compileroption in einer Entwicklerbefehlsaufforderung , um die Kompilierung für die AddressSanitizer-Laufzeit zu aktivieren. Die /fsanitize=address Option ist mit allen vorhandenen C++- oder C-Optimierungsstufen kompatibel (z. B. , /O2/O2 /GL/Od/O1und ).PGO Die Option funktioniert mit statischen und dynamischen CRTs (z. B. , /MD, /MDd, /MTund /MTd). Es funktioniert, ob Sie eine EXE oder eine DLL erstellen. Debuginformationen sind für die optimale Formatierung von Anrufstapeln erforderlich. Im folgenden cl /fsanitize=address /Zi Beispiel wird die Befehlszeile übergeben.

Die AddressSanitizer-Bibliotheken (.lib-Dateien) werden automatisch verknüpft. Weitere Informationen finden Sie unter AddressSanitizer-Sprache, Build- und Debugreferenz.

Beispiel : grundlegende globaler Pufferüberlauf

// basic-global-overflow.cpp
#include <stdio.h>
int x[100];
int main() {
    printf("Hello!\n");
    x[100] = 5; // Boom!
    return 0;
}

Verwenden einer Entwicklerbefehlsaufforderung für Visual Studio 2019, Kompilieren main.cpp mithilfe von/fsanitize=address /Zi

Screenshot of a command prompt showing the command to compile with AddressSanitizer options.

Wenn Sie die resultierende main.exe Ausführung in der Befehlszeile ausführen, erstellt sie den formatierten Fehlerbericht unten.

Betrachten Sie die überlagerten, roten Felder, die sieben wichtige Informationen hervorheben:

Screenshot of the debugger showing a basic global overflow error.

Rote Hervorhebungen, von oben bis unten

  1. Der Speichersicherheitsfehler ist ein globaler Pufferüberlauf.
  2. Es gab 4 Bytes (32 Bit) außerhalb einer benutzerdefinierten Variable gespeichert .
  3. Der Speicher wurde in der In-Datei main()basic-global-overflow.cpp in Zeile 7 definiert.
  4. Die Variable mit dem Namen x wird in "basic-global-overflow.cpp" in Zeile 3 ab Spalte 8 definiert.
  5. Diese globale Variable x ist von Größe 400 Bytes
  6. Der genaue Schatten-Byte , der die von dem Speicher gezielte Adresse beschreibt, hatte einen Wert von 0xf9
  7. Die Schatten-Byte-Legende sagt 0xf9 , dass es sich um einen Bereich des Abstands rechts von int x[100]

Hinweis

Die Funktionsnamen im Anrufstapel werden über das LLVM-Symbol erstellt, das vom Laufzeitfehler aufgerufen wird.

Verwenden des AddressSanitizers in Visual Studio

AddressSanitizer ist in die Visual Studio IDE integriert. Wenn Sie den AddressSanitizer für ein MSBuild Projekt aktivieren möchten, klicken Sie mit der rechten Maustaste auf das Projekt in Projektmappen-Explorer, und wählen Sie "Eigenschaften" aus. Wählen Sie im Dialogfeld "Eigenschaftenseiten " KonfigurationseigenschaftenC>/C++>Allgemein aus, und ändern Sie dann die Eigenschaft "AddressSanitizer aktivieren ". Klicken Sie auf OK, um die Änderungen zu speichern.

Screenshot of the Property Pages dialog showing the Enable AddressSanitizer property.

Um aus der IDE zu erstellen, deaktivieren Sie alle inkompatiblen Optionen. Für ein vorhandenes Projekt, das mithilfe /Od von (oder Debugmodus) kompiliert wurde, müssen Sie möglicherweise diese Optionen deaktivieren:

Geben Sie F5 ein, um den Debugger zu erstellen und auszuführen. In Visual Studio wird dieses Fenster angezeigt:

Screenshot of the debugger showing a global buffer overflow error.

Verwenden des AddressSanitizers aus Visual Studio: CMake

Führen Sie die folgenden Schritte aus, um den AddressSanitizer für ein CMake-Projekt zu aktivieren, das zum Ziel Windows erstellt wurde:

  1. Öffnen Sie die Dropdownliste "Konfigurationen " in der Symbolleiste oben in der IDE, und wählen Sie " Konfigurationen verwalten" aus.

    Screenshot of the CMake configuration dropdown.

    Diese Auswahl öffnet den CMake Project Einstellungen-Editor, der in einer CMakeSettings.json-Datei gespeichert wird.

  2. Wählen Sie den JSON-Link bearbeiten im Editor aus. Diese Auswahl wechselt die Ansicht in unformatierte JSON.

  3. Fügen Sie die Eigenschaft hinzu: "addressSanitizerEnabled": true

    Dieses Bild ist von CMakeSettings.json nach dieser Änderung:

    Screenshot of the text editor view of CMakeSettings.json.

  4. Geben Sie STRG+S ein, um diese JSON-Datei zu speichern, und geben Sie F5 ein, um unter dem Debugger neu zu kompilieren und auszuführen.

Dieser Screenshot erfasst den Fehler aus dem CMake-Build.

Screenshot of the CMake build error message.

AddressSanitizer-Absturzabbilder

Wir haben neue Funktionen im AddressSanitizer für die Verwendung mit Cloud- und verteilten Workflows eingeführt. Diese Funktionalität ermöglicht die Offlineanzeige eines AddressSanitizer-Fehlers in der IDE. Der Fehler wird oben in Ihrer Quelle überlagert, genauso wie Sie in einer Live-Debugsitzung auftreten würden.

Diese neuen Dumpdateien können bei der Analyse eines Fehlers zu Effizienz führen. Sie müssen keine Remotedaten erneut ausführen oder nach einem Computer suchen, der deaktiviert wurde.

So erstellen Sie eine neue Art von Dumpdatei, die in Visual Studio auf einem anderen Computer zu einem späteren Zeitpunkt angezeigt werden kann:

set ASAN_SAVE_DUMPS=MyFileName.dmp

Ab Visual Studio 16.9 können Sie einen genau diagnostizierten Fehler anzeigen, der in Ihrer *.dmp Datei gespeichert ist, oben im Quellcode.

Diese neue Absturzabbildfunktion ermöglicht cloudbasierte Workflows oder verteilte Tests. Es kann auch verwendet werden, um einen detaillierten, aktionsfähigen Fehler in jedem Szenario zu speichern.

Fehlerbeispiele

AddressSanitizer kann verschiedene Arten von Speicherfehlern erkennen. Nachfolgend finden Sie viele der Laufzeitfehler, die beim Ausführen ihrer Binärdateien mithilfe der Option "AddressSanitizer" (/fsanitize=address) gemeldet wurden:

Weitere Informationen zu den Beispielen finden Sie unter AddressSanitizer-Fehlerbeispiele.

Unterschiede mit Clang 12.0

MSVC unterscheidet sich derzeit von Clang 12.0 in zwei Funktionsbereichen:

  • stack-use-after-scope - diese Einstellung ist standardmäßig aktiviert und kann nicht deaktiviert werden.
  • stack-use-after-return - diese Funktionalität erfordert eine zusätzliche Compileroption und ist nicht nur durch Einstellung ASAN_OPTIONSverfügbar.

Diese Entscheidungen wurden getroffen, um die Testmatrix zu reduzieren, die erforderlich ist, um diese erste Version bereitzustellen.

Features, die zu falsch positiven Ergebnissen in Visual Studio 2019 16.9 führen könnten, waren nicht enthalten. Diese Disziplin erzwungene die effektive Testintegrität, die bei der Erwägung der Interop mit Jahrzehnten bestehendem Code erforderlich ist. Weitere Funktionen können in späteren Versionen berücksichtigt werden:

Weitere Informationen finden Sie unter Building for the AddressSanitizer with MSVC.

Vorhandene Branchendokumentation

Umfangreiche Dokumentationen sind bereits für diese sprach- und plattformabhängigen Implementierungen der AddressSanitizer-Technologie vorhanden.

Dieses seminale Papier im AddressSanitizer beschreibt die Implementierung.

Siehe auch

Bekannte Probleme von AddressSanitizer
Kompilierungs- und Sprachreferenz für AddressSanitizer
Runtimereferenz für AddressSanitizer
AddressSanitizer-Schattenbytes
AddressSanitizer-Tests in der Cloud oder verteilten Umgebungen
Integration des AddressSanitizer-Debuggers
AddressSanitizer-Fehlerbeispiele