Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Ü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/deleteTypenkonflikten - Zu große Allokationen für den Heap
-
callocÜberlauf undallocaÜberlauf - Doppelfreigabe und Verwendung nach Freigabe
- Globaler Variablenüberlauf
- Heap-Pufferüberlauf
- Ungültige Ausrichtung von ausgerichteten Werten
-
memcpyundstrncatParameterüberlappung - Stapelpufferüberlauf und Unterlauf
-
Stapelverwendung nach
returnund Verwendung nach Bereich - Speichereinsatz nach dem Vergiften
Verwenden Sie AddressSanitizer, um den 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 festlegen, bevor Sie Ihr Programm ausführen, wird eine Absturzabbilddatei mit zusätzlichen Metadaten erstellt, die ein effizientes Post-Mortem-Debugging präzise diagnostizierter Fehler 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ü unter Tools>Tools und Features abrufen... Wählen Sie Ändern für Ihre vorhandene Visual Studio-Installation im Visual Studio-Installer, 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:
- Befehlszeilen-Erstellungen
- Visual Studio-Projektsystem
- Visual Studio CMake-Integration
Kompilieren Sie das Programm erneut und führen Sie es dann normalerweise aus. 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-Dumpdateien
Fuzzing - Kompilieren 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 bereits veröffentlichte hervorragende Dokumentation von Google, Apple und GCC.
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. B. /fsanitize=thread, /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 option /fsanitize=address ist kompatibel mit vorhandenen C++- oder C-Optimierungsstufen (z. B. /Od, /O1, /O2und /O2 /GL). Die Option funktioniert mit statischen und dynamischen CRTs (z. B. /MD, /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 wird cl /fsanitize=address /Zi in der Befehlszeile übergeben.
Hinweis
AddressSanitizer unterstützt keine profilgeführte Optimierung (Profile-guided optimization, PGO). AddressSanitizer sollte nicht in der Produktion verwendet werden.
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;
}
Verwenden Sie eine Entwickler-Eingabeaufforderung für Visual Studio 2019, um main.cpp mit /fsanitize=address /Zi zu kompilieren
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) SCHREIBEN von Größe 4 3) basic-global-overflow.cpp 7 4) rechts von der globalen Variable 'x', die in 'basic-global-overflow.cpp:3:8' definiert ist 5) von Größe 400 6) 00 00[f9]f9 f9 f9 7) Feld befindet sich im Bereich der Schattenbyte-Legende und enthält 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 Store fand in der Funktion
main()statt, die in Dateibasic-global-overflow.cppin Zeile 7 definiert ist. - Die benannte
xVariable wird in basic-global-overflow.cpp in Zeile 3 definiert, beginnend mit Spalte 8 - Diese globale Variable
xhat 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, dass
0xf9ein Bereich mit Polsterung rechts vonint x[100]ist.
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:
- Deaktivieren
/ZI(Debuginformationsformat) -
/RTC1(Laufzeitüberprüfungen deaktivieren) - 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.jsonwiderspiegelt.Wählen Sie den Link JSON 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
"windows-base"Voreinstellung hinzu, innerhalb von"configurePresets":, um AddressSanitizer zu aktivieren."environment": { "CFLAGS": "/fsanitize=address", "CXXFLAGS": "/fsanitize=address" }"configurePresets"sieht danach ungefähr so 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" } },AddressSanitizer funktioniert nicht, wenn "Edit-and-continue" angegeben ist (
/ZI), das standardmäßig für neue CMake-Projekte aktiviert ist. Kommentieren Sie die Zeile inCMakeLists.txt, die mitset(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT"beginnt, indem Sie#davor setzen. Diese Zeile sieht anschließend 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 über Ihrem Quellcode angezeigt, so wie Sie es in einer Live-Debug-Sitzung erleben würden.
Diese neuen Speicherabbilddateien können bei der Analyse eines Fehlers Effizienzen ermöglichen. Sie müssen den Vorgang nicht erneut ausführen, keine Remotedaten abrufen oder nach einem Gerät suchen, das offline gegangen ist.
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-mismatchallocation-size-too-bigcalloc-overflowdouble-freedynamic-stack-buffer-overflowglobal-buffer-overflowheap-buffer-overflowheap-use-after-freeinvalid-allocation-alignmentmemcpy-param-overlapnew-delete-type-mismatchstack-buffer-overflowstack-buffer-underflowstack-use-after-returnstack-use-after-scopestrncat-param-overlapuse-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_OPTIONSverfü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 für die Interoperabilität mit seit 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 Entwickeln für AddressSanitizer mit 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
Bekannte Probleme mit AddressSanitizer
AddressSanitizer Build- und Sprachreferenz
AddressSanitizer-Laufzeitreferenz
AddressSanitizer-Schattenbytes
AddressSanitizer-Cloud oder verteilte Tests
AddressSanitizer-Debugger-Integration
Beispiele für AddressSanitizer-Fehler