AddressSanitizer
Übersicht
Die C & C++-Sprachen sind leistungsfähig, können aber unter einer Klasse von Fehlern leiden, die die Programmkorrektur und Programmsicherheit beeinflussen. Ab Visual Studio 2019, Version 16.9, unterstützt der Microsoft C/C++-Compiler (MSVC) und die IDE den AddressSanitizer-Sanitizer . AddressSanitizer (ASan) ist eine Compiler- und Laufzeittechnologie, die viele schwer zu findende Fehler mit null falsch positiven Ergebnissen verfügbar macht:
- Alloc/dealloc-Nichtübereinstimmungen und/
new
delete
Typenkonflikten - Zu große Zuordnungen für den Heap
calloc
Überlauf undalloca
Überlauf- Double free and use after free
- Globaler Variablenüberlauf
- Heappufferüberlauf
- Ungültige Ausrichtung von ausgerichteten Werten
memcpy
undstrncat
Parameterüberlappung- Stapelpufferüberlauf und Unterlauf
- Stack use after
return
and use after scope - Speichereinsatz nach dem Vergiften
Verwenden Sie AddressSanitizer, um Ihre Zeitaufwand zu reduzieren:
- Grundlegende Korrektheit
- Plattformübergreifende Portabilität
- Sicherheit
- Belastungstest
- Integrieren von neuem Code
AddressSanitizer, ursprünglich von Google eingeführt, bietet Laufzeit-Fehlersuche-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 die AddressSanitizer-Technologie von Microsoft die Integration in die Visual Studio-IDE. Die Funktionalität kann optional eine Absturzabbilddatei erstellen, wenn der Sanitizer zur Laufzeit einen Fehler findet. Wenn Sie die ASAN_SAVE_DUMPS=MyFileName.dmp
Umgebungsvariable vor dem Ausführen des Programms festlegen, wird eine Absturzabbilddatei mit zusätzlichen Metadaten erstellt, um das effiziente Debuggen nach der Mortem-Analyse präzise diagnostizierter Fehler zu ermöglichen. Diese Dumpdateien vereinfachen die erweiterte Verwendung von AddressSanitizer für:
- Testen lokaler Computer
- Lokale verteilte Tests
- Cloudbasierte Workflows zum Testen
Installieren von AddressSanitizer
C++-Workloads im Visual Studio-Installer standardmäßig die AddressSanitizer-Bibliotheken und die IDE-Integration installieren. Wenn Sie jedoch ein Upgrade von einer älteren Version von Visual Studio 2019 durchführen, verwenden Sie das Installationsprogramm, um die ASan-Unterstützung nach dem Upgrade zu aktivieren. Sie können das Installationsprogramm über das Visual Studio-Hauptmenü über Tools>abrufen Tools und Features öffnen... Wählen Sie "Ändern" für Ihre vorhandene Visual Studio-Installation aus dem Visual Studio-Installer aus, um zum folgenden Bildschirm zu gelangen.
Hinweis
Wenn Sie Visual Studio auf dem neuen Update ausführen, aber ASan nicht installiert haben, wird beim Ausführen des Codes eine Fehlermeldung angezeigt:
LNK1356: Bibliothek "clang_rt.asan_dynamic-i386.lib" wurde nicht gefunden.
Verwenden von AddressSanitizer
Beginnen Sie mit dem Erstellen Ihrer ausführbaren Dateien mit der /fsanitize=address
Compileroption, indem Sie eine der folgenden allgemeinen Entwicklungsmethoden verwenden:
- Befehlszeilenbuilds
- Visual Studio-Projektsystem
- Visual Studio CMake-Integration
Kompilieren Sie das Programm dann normal. Diese Codegenerierung macht viele Arten genau diagnostizierter Fehler verfügbar. Diese Fehler werden auf drei Arten gemeldet: in der Debugger-IDE, in der Befehlszeile oder in einem neuen Speicherabbilddateityp für eine präzise Offlineverarbeitung.
Microsoft empfiehlt die Verwendung von AddressSanitizer in diesen drei Standardworkflows:
Innere Schleife für Entwickler
- Visual Studio – Befehlszeile
- Visual Studio – Project-System
- Visual Studio – CMake
CI/CD - kontinuierliche Integration / kontinuierliche Entwicklung
- Fehlerberichterstattung – Neue AddressSanitizer-Speicherabbilddateien
Fuzzing - Erstellen mit dem libFuzzer Wrapper
- Azure OneFuzz
- Lokaler Computer
In diesem Artikel werden die Informationen behandelt, die Sie benötigen, um die drei zuvor aufgeführten Workflows zu aktivieren. Die Informationen sind spezifisch für die plattformabhängige Windows 10-Implementierung (und höher) von AddressSanitizer. Diese Dokumentation ergänzt die hervorragende Dokumentation von Google, Apple und GCC bereits veröffentlicht.
Hinweis
Die Unterstützung ist auf x86 und x64 unter Windows 10 und höher beschränkt. Senden Sie uns Feedback dazu, was Sie in zukünftigen Versionen sehen möchten. Ihr Feedback hilft uns, andere Bereinigungsmittel für die Zukunft zu priorisieren, z /fsanitize=thread
. B. , , /fsanitize=leak
, /fsanitize=memory
, /fsanitize=undefined
oder /fsanitize=hwaddress
. Sie können hier Fehler melden, wenn Probleme auftreten.
Verwenden von AddressSanitizer über eine Entwickler-Eingabeaufforderung
Verwenden Sie die /fsanitize=address
Compileroption in einer Entwickler-Eingabeaufforderung , um die Kompilierung für die AddressSanitizer-Laufzeit zu aktivieren. Die /fsanitize=address
Option ist mit allen vorhandenen C++- oder C-Optimierungsstufen kompatibel (z/Od
. B. , , /O1
, /O2
, und /O2 /GL
PGO
). Die Option funktioniert mit statischen und dynamischen CRTs (z /MD
. B. , , /MDd
, /MT
und /MTd
). Es funktioniert, ob Sie eine EXE- oder DLL-Datei erstellen. Debuginformationen sind für eine optimale Formatierung von Aufrufstapeln erforderlich. Im folgenden Beispiel cl /fsanitize=address /Zi
wird die Befehlszeile übergeben.
Die AddressSanitizer-Bibliotheken (LIB-Dateien) werden automatisch verknüpft. Weitere Informationen finden Sie unter AddressSanitizer-Sprache, Build- und Debuggingreferenz.
Beispiel : einfacher globaler Pufferüberlauf
// basic-global-overflow.cpp
#include <stdio.h>
int x[100];
int main() {
printf("Hello!\n");
x[100] = 5; // Boom!
return 0;
}
Kompilieren main.cpp
mithilfe einer Entwickler-Eingabeaufforderung für Visual Studio 2019 /fsanitize=address /Zi
Wenn Sie das Ergebnis main.exe
an der Befehlszeile ausführen, wird der folgende formatierte Fehlerbericht erstellt.
Betrachten Sie die überlagerten roten Felder, die sieben wichtige Informationen hervorheben:
Es gibt sieben rote Highlights, die wichtige Informationen im Fehlerbericht identifizieren. Sie werden der nummerierten Liste zugeordnet, die diesem Screenshot folgt. Die nummerierten Felder markieren den folgenden Text: 1) Global-Buffer-Overflow 2) WRITE of size 4 3) basic-global-overflow.cpp 7 4) to the right of global variable 'x' defined in 'basic-global-overflow.cpp:3:8' 5) of size 400 6) 00 00[f9]f9 f9 f9 7) Box is in the shadow byte legend area and contains Global redzone: f9
Rote Hervorhebungen von oben nach unten
- Der Speichersicherheitsfehler ist ein globaler Pufferüberlauf.
- Außerhalb einer benutzerdefinierten Variablen wurden 4 Bytes (32 Bit) gespeichert .
- Der Speicher wurde in Der Datei
main()
in Zeilebasic-global-overflow.cpp
7 definiert. - Die benannte
x
Variable wird in basic-global-overflow.cpp in Zeile 3 definiert, beginnend mit Spalte 8 - Diese globale Variable
x
hat eine Größe von 400 Byte. - Das genaue Schattenbyte , das die Adresse beschreibt, auf die der Speicher abzielt, hat einen Wert von
0xf9
- Die Schattenbytelegende sagt,
0xf9
dass es sich um einen Bereich mit Abstand rechts vonint x[100]
Hinweis
Die Funktionsnamen im Aufrufstapel werden über den LLVM-Symboler erzeugt, der von der Laufzeit beim Fehler aufgerufen wird.
Verwenden von AddressSanitizer in Visual Studio
AddressSanitizer ist in die Visual Studio-IDE integriert. Um AddressSanitizer für ein MSBuild-Projekt zu aktivieren, klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie "Eigenschaften" aus. Wählen Sie im Dialogfeld "Eigenschaftenseiten" die Option "Konfigurationseigenschaften>C/C++>Allgemein" aus, und ändern Sie dann die Eigenschaft "AddressSanitizer aktivieren". Klicken Sie auf OK, um die Änderungen zu speichern.
Um aus der IDE zu erstellen, deaktivieren Sie alle inkompatiblen Optionen. Für ein vorhandenes Projekt, das mithilfe des /Od
(oder Debugmodus) kompiliert wurde, müssen Sie diese Optionen möglicherweise deaktivieren:
- Bearbeiten deaktivieren und fortfahren
- Deaktivieren
/RTC1
(Laufzeitüberprüfungen) - Deaktivieren
/INCREMENTAL
(inkrementelle Verknüpfung)
Drücken Sie F5, um den Debugger zu erstellen und auszuführen. Ein Fenster "Ausnahme ausgelöst " wird in Visual Studio angezeigt:
Verwenden von AddressSanitizer aus Visual Studio: CMake
Führen Sie die folgenden Schritte aus, um AddressSanitizer für ein für Windows erstelltes CMake-Projekt zu aktivieren:
Öffnen Sie die Dropdownliste "Konfigurationen" in der Symbolleiste am oberen Rand der IDE, und wählen Sie "Konfigurationen verwalten" aus.
Dadurch wird der CMake-Projekteinstellungen-Editor geöffnet, der den Inhalt der Projektdatei
CMakeSettings.json
widerspiegelt.Wählen Sie den JSON-Link bearbeiten im Editor aus. Diese Auswahl wechselt die Ansicht in unformatierte JSON.This selection switches the view to raw JSON.
Fügen Sie den folgenden Codeausschnitt zur Voreinstellung hinzu, um
"configurePresets":
die"windows-base"
Adressbereinigung zu aktivieren:"environment": { "CFLAGS": "/fsanitize=address", "CXXFLAGS": "/fsanitize=address" }
"configurePresets"
sieht wie folgt aus:"configurePresets": [ { "name": "windows-base", "hidden": true, "generator": "Ninja", "binaryDir": "${sourceDir}/out/build/${presetName}", "installDir": "${sourceDir}/out/install/${presetName}", "cacheVariables": { "CMAKE_C_COMPILER": "cl.exe", "CMAKE_CXX_COMPILER": "cl.exe" }, "condition": { "type": "equals", "lhs": "${hostSystemName}", "rhs": "Windows" }, "environment": { "CFLAGS": "/fsanitize=address", "CXXFLAGS": "/fsanitize=address" } },
Adressbereinigung funktioniert nicht, wenn "Bearbeiten und Fortsetzen" angegeben ist (
/ZI
), das standardmäßig für neue CMake-Projekte aktiviert ist. KommentierenCMakeLists.txt
Sie in , kommentieren (Präfix mit#
) die Zeile, die mitset(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT"
. Diese Zeile sieht ungefähr wie folgt aus:# set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
Drücken Sie STRG+S , um diese JSON-Datei zu speichern.
Löschen Sie das CMake-Cacheverzeichnis, und konfigurieren Sie es neu, indem Sie im Menü "Visual Studio" die Option "Cache>löschen" und "Neu konfigurieren" auswählen. Wählen Sie "Ja " aus, wenn die Eingabeaufforderung angezeigt wird, um das Cacheverzeichnis zu löschen und neu zu konfigurieren.
Ersetzen Sie den Inhalt der Quelldatei (z. B
CMakeProject1.cpp
. ) durch Folgendes:// CMakeProject1.cpp : Defines the entry point for the application #include <stdio.h> int x[100]; int main() { printf("Hello!\n"); x[100] = 5; // Boom! return 0; }
Wählen Sie F5 aus, um das Kompilieren neu zu kompilieren und unter dem Debugger auszuführen.
Dieser Screenshot erfasst den Fehler aus dem CMake-Build.
AddressSanitizer-Absturzabbilder
Wir haben neue Funktionen in 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 der Quelle überlagert, genau wie in einer Live-Debugsitzung.
Diese neuen Speicherabbilddateien 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 offline war.
So erstellen Sie eine neue Art von Dumpdatei, die in Visual Studio zu einem späteren Zeitpunkt auf einem anderen Computer angezeigt werden kann:
set ASAN_SAVE_DUMPS=MyFileName.dmp
Ab Visual Studio 16.9 können Sie oben im Quellcode einen genau diagnostizierten Fehler anzeigen, der in Ihrer *.dmp
Datei gespeichert ist.
Diese neue Absturzabbildfunktion ermöglicht cloudbasierte Workflows oder verteilte Tests. Es kann auch verwendet werden, um einen detaillierten, umsetzbaren Fehler in jedem Szenario zu speichern.
Beispielfehler
AddressSanitizer kann verschiedene Arten von Speichermissbrauchsfehlern erkennen. Im Folgenden werden viele der Laufzeitfehler gemeldet, wenn Sie ihre Binärdateien mithilfe der Compileroption AddressSanitizer (/fsanitize=address
) kompiliert ausführen:
alloc-dealloc-mismatch
allocation-size-too-big
calloc-overflow
double-free
dynamic-stack-buffer-overflow
global-buffer-overflow
heap-buffer-overflow
heap-use-after-free
invalid-allocation-alignment
memcpy-param-overlap
new-delete-type-mismatch
stack-buffer-overflow
stack-buffer-underflow
stack-use-after-return
stack-use-after-scope
strncat-param-overlap
use-after-poison
Weitere Informationen zu den Beispielen finden Sie unter AddressSanitizer-Fehlerbeispiele.
Unterschiede bei 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 Festlegen
ASAN_OPTIONS
verfügbar.
Diese Entscheidungen wurden getroffen, um die für die Bereitstellung dieser ersten Version erforderliche Testmatrix zu reduzieren.
Features, die zu falsch positiven Ergebnissen in Visual Studio 2019 16.9 führen könnten, wurden nicht einbezogen. Diese Disziplin hat die effektive Testintegrität erzwungen, die bei der Interoperabilität mit jahrzehnten bestehendem Code erforderlich ist. Weitere Funktionen können in späteren Versionen berücksichtigt werden:
- Initialisierungsreihenfolge Fiasco
- Intra-Objektüberlauf
- Containerüberlauf
- Zeigeruntertraktion/Vergleich
Weitere Informationen finden Sie unter Building for AddressSanitizer with MSVC.
Vorhandene Branchendokumentation
Umfangreiche Dokumentationen sind bereits für diese sprach- und plattformabhängigen Implementierungen der AddressSanitizer-Technologie vorhanden.
In diesem seminalen Dokument zum AddressSanitizer (extern) wird die Implementierung beschrieben.
Siehe auch
Beheben bekannter Probleme mit demSanitizer
AddressSanitizer Build- und Sprachreferenz
AddressSanitizer-Laufzeitreferenz
AddressSanitizer-Schattenbytes
AddressSanitizer-Cloud oder verteilte Tests
AddressSanitizer Debugger-Integration
Beispiele für AddressSanitizer-Fehler