AddressSanitizer

Übersicht

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

Verwenden Sie AddressSanitizer, um Ihre Zeit für Dies zu reduzieren:

  • Grundlegende Richtigkeit
  • Plattformübergreifende Portabilität
  • Sicherheit
  • Belastungstest
  • Integrieren von neuem Code

AddressSanitizer, ursprünglich von Googleeingeführt, ist eine leistungsstarke Alternative zu sowohl (Laufzeitfehlerüberprüfungen) als auch (statische Analyse). Es stellt Laufzeit-Technologien zur Fehlersuche zur Verfügung, die Ihre vorhandenen Buildsysteme und vorhandenen 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 Optimierungsebenen und Konfigurationen von x86 und x64 kompatibel. Sie ist jedoch nicht kompatibel mit edit-and-continue,inkrementeller Verknüpfungund .

Ab Visual Studio 2019 Version 16.9 ermöglicht die AddressSanitizer-Technologie von Microsoft die Integration in die Visual Studio-IDE. Die Funktionalität kann optional eine Absturzabbilddatei erstellen, wenn der Besender zur Laufzeit einen Fehler findet. Wenn Sie die Umgebungsvariable festlegen, bevor Sie das Programm ausführen, wird eine Absturzabbilddatei mit zusätzlichen Metadaten für ein effizientes nachträgliches Debuggen von genau ASAN_SAVE_DUMPS=MyFileName.dmp diagnostizierten Fehlern ASAN_SAVE_DUMPS=MyFileName.dmp erstellt. Diese Dumpdateien erleichtern die erweiterte Verwendung von AddressSanitizer für:

  • Tests lokaler Computer,
  • Lokale verteilte Tests und
  • Cloudbasierte Workflows für Tests.

Installieren von AddressSanitizer

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

Visual Studio Installer screenshot highlighting the C++ AddressSanitizer component

Sie können ändern für Ihre vorhandene Visual Studio-Installation aus dem Visual Studio-Installer, um zum obigen Bildschirm zu kommen.

Hinweis

Wenn Sie Visual Studio neuen Update ausführen, aber ASan nicht installiert haben, erhalten Sie beim Ausführen des Codes eine Fehlermeldung:

LNK1356: Die Bibliothek "clang_rt.asan_dynamic-i386.lib" wurde nicht finden.

Verwenden von AddressSanitizer

Beginnen Sie mit dem Erstellen Ihrer ausführbaren Dateien /fsanitize=address mit der Compileroption, indem Sie eine der folgenden gängigen Entwicklungsmethoden verwenden:

  • Befehlszeilen-Builds
  • Visual Studio-Projektsystem
  • Visual Studio CMake-Integration

Kompilieren Sie das Programm erneut, und führen Sie es dann normal aus. Diese Codegenerierung macht viele Arten von genau diagnostizierten Fehlern verfügbar. Diese Fehler werden auf drei Arten gemeldet: in der Debugger-IDE, in der Befehlszeile oder in einer neuen Art von Dumpdatei für eine präzise Off-Line-Verarbeitung.

Microsoft empfiehlt die Verwendung von AddressSanitizer in diesen drei Standardworkflows:

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

Hinweis

Die aktuelle Unterstützung ist auf x86 und x64 auf Windows 10. Senden Sie uns Feedback dazu, was Sie in zukünftigen Releases sehen möchten. Ihr Feedback hilft uns dabei, andere Beregnungser für die Zukunft zu priorisieren, z. B. /fsanitize=thread , , , oder /fsanitize=leak/fsanitize=memory/fsanitize=undefined/fsanitize=hwaddress . Sie können hier Fehler melden, wenn Probleme auft kommen.

Verwenden von AddressSanitizer über eine Developer-Eingabeaufforderung

Verwenden Sie /fsanitize=address die Compileroption in einer /fsanitize=address um die Kompilierung für die AddressSanitizer-Runtime zu aktivieren. Die /fsanitize=address Option ist mit allen vorhandenen C++- oder C-Optimierungsebenen kompatibel (z. B. /Od , , , und /O1/O2/O2 /GLPGO ). Die Option funktioniert mit statischen und dynamischen CRTs (z. B. /MD/MDd , , und /MT/MTd ). Dies funktioniert unabhängig davon, ob Sie eine EXE- oder DLL-Datei erstellen. Debuginformationen sind für eine optimale Formatierung von Aufrufstapeln erforderlich. Im folgenden Beispiel wird cl /fsanitize=address /Zi in der Befehlszeile übergeben.

Die AddressSanitizer-Bibliotheken (LIB-Dateien) werden automatisch verknüpft. Weitere Informationen finden Sie in der AddressSanitizer-Sprach-, Build- und Debugreferenz.

Beispiel: grundlegender 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 Developer-Eingabeaufforderung für Visual Studio 2019, Kompilieren mit main.cpp/fsanitize=address /Zi

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

Wenn Sie den resultierenden main.exe in der Befehlszeile ausführen, wird der formatierte Fehlerbericht erstellt, der unten angezeigt wird.

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

Screenshot of the debugger showing a basic global overflow error.

Rote Highlights von oben nach unten

  1. Der Arbeitsspeichersicherheitsfehler ist ein globaler Pufferüberlauf.
  2. Es wurden 4 Bytes (32 Bits) außerhalb einer benutzerdefinierten Variablen gespeichert.
  3. Der Speicher erfolgte in der Funktion, main() die in der Datei in Zeile basic-global-overflow.cpp 7 definiert wurde.
  4. Die Variable mit dem Namen wird ab Spalte x 8 in basic-global-overflow.cpp in Zeile 3 definiert.
  5. Diese globale Variable x hat eine Größe von 400 Bytes.
  6. Das genaue Schatten byte, das die Adresse beschreibt, auf die der Speicher ausgerichtet ist, hatte den Wert
  7. Die Schatten bytelegende besagt, dass es sich um einen Bereich mit 0xf9 Auf padding rechts von handelt. int x[100]

Hinweis

Die Funktionsnamen in der Aufrufliste werden über den LLVM-Automaten erstellt, der bei einem Fehler von der Laufzeit aufgerufen wird.

Verwenden des AddressSanitizer in Visual Studio

AddressSanitizer ist in die Visual Studio integriert. Um addressSanitizer für ein projektspezifisches MSBuild zu aktivieren, klicken Sie mit der rechten Maustaste auf das Projekt in Projektmappen-Explorer und wählen Eigenschaften aus. Wählen Sie im Dialogfeld Eigenschaftenseiten die Option 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.

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

Geben Sie F5 ein, um den Debugger zu erstellen und auszuführen. Dieses Fenster wird in der Visual Studio:

Screenshot of the debugger showing a global buffer overflow error.

Verwenden des AddressSanitizer aus Visual Studio: CMake

Führen Sie die folgenden Schritte aus, um AddressSanitizer für ein CMake-Projektzu aktivieren, das für 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 ist.

  2. Klicken Sie im Editor auf den Link JSON bearbeiten. Durch diese Auswahl wird die Ansicht in json-Rohdaten umgeschaltet.

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

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

    Screenshot of the text editor view of CMakeSettings.json.

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

Dieser Screenshot zeigt den Fehler aus dem CMake-Build.

Screenshot of the CMake build error message.

AddressSanitizer-Absturzabbild

Wir haben neue Funktionen in AddressSanitizer für die Verwendung mit Cloudworkflows und verteilten Workflows eingeführt. Diese Funktionalität ermöglicht die Offlineanzeige eines AddressSanitizer-Fehlers in der IDE. Der Fehler wird auf Ihre Quelle überlagert, genau wie bei einer Livedebugsitzung.

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

So erstellen Sie einen neuen Typ von Dumpdatei, der zu einem späteren Visual Studio auf einem anderen Computer angezeigt werden kann:

set ASAN_SAVE_DUMPS=MyFileName.dmp

Ab Visual Studio 16.9 können Sie zusätzlich zum Quellcode einen genau diagnostizierten Fehler anzeigen, der in Ihrer Datei gespeichert ist.

Diese neue Absturzabbildfunktion ermöglicht cloudbasierte Workflows oder verteilte Tests. Sie kann auch verwendet werden, um in jedem Szenario einen detaillierten, umsetzbaren Fehler zu melden.

Fehlerbeispiele

AddressSanitizer kann verschiedene Arten von Speicherfehlern erkennen. Hier sind viele der Laufzeitfehler, die gemeldet werden, wenn Sie Die Binärdateien ausführen, die mithilfe der Compileroption AddressSanitizer ( /fsanitize=address ) kompiliert wurden:

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

Unterschiede zu Clang 12.0

MSVC unterscheidet sich derzeit in zwei Funktionbereichen von Clang 12.0:

  • stack-use-after-scope: Diese Einstellung ist standardmäßig aktiviert und kann nicht deaktiviert werden.
  • stack-use-after-return: Diese Funktion erfordert eine zusätzliche Compileroption und ist nicht verfügbar, indem nur die -Einstellung verwendet wird.

Diese Entscheidungen wurden getroffen, um die Testmatrix zu reduzieren, die für die Bereitstellung dieser ersten Version erforderlich ist.

Features, die zu falsch positiven Visual Studio 2019 16.9 führen könnten, wurden nicht einbezogen. Diese Disziplin erzwingt die effektive Testintegrität, die erforderlich ist, wenn interop mit bereits seit Jahrzehnten bestehendem Code in Betracht ziehen wird. Weitere Funktionen können in späteren Versionen in Betracht gezogen werden:

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

Vorhandene Branchendokumentation

Für diese sprach- und plattformabhängigen Implementierungen der AddressSanitizer-Technologie ist bereits eine umfassende Dokumentation vorhanden.

In diesem Seminal paper on the AddressSanitizer (AddressSanitizer) wird die Implementierung beschrieben.

Weitere Informationen:

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