Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Vue d’ensemble
Les langages C et C++ sont puissants, mais peuvent souffrir d’une classe de bogues qui affectent la correction du programme et la sécurité du programme. À partir de Visual Studio 2019 version 16.9, le compilateur Microsoft C/C++ (MSVC) et l’IDE prennent en charge l’outil d’assainissement AddressSanitizer. AddressSanitizer (ASan) est une technologie de compilateur et d’exécution qui expose de nombreux bogues difficiles à trouver avec zéro faux positifs :
-
Incompatibilités alloc/dealloc et
new/deleteincompatibilités de type - Allocations trop grandes pour le tas
-
callocdébordement etallocadébordement - Double libération et utilisation après libération
- Surcharge de variable globale
- Dépassement de mémoire tampon du tas
- Alignement non valide des valeurs alignées
-
memcpyetstrncatchevauchement des paramètres - Dépassement de tampon de pile et sous-dépassement
-
Utilisation de la pile après
returnet utilisation après la portée - Utilisation de la mémoire après empoisonnement
Pourquoi utiliser AddressSanitizer
Utilisez AddressSanitizer pour réduire votre temps passé à :
- Correction fondamentale
- Portabilité multiplateforme
- Sécurité
- Tests de contrainte
- Intégration de nouveau code
AddressSanitizer, initialement introduit par Google, fournit des technologies de recherche de bogues d’exécution qui utilisent directement vos systèmes de build existants et les ressources de test existantes.
Créer l’intégration et la compatibilité
AddressSanitizer est intégré au système de projet Visual Studio, au système de génération CMake et à l’IDE. Les projets peuvent activer AddressSanitizer en définissant une propriété de projet ou en utilisant une option de compilateur supplémentaire : /fsanitize=address. Cette option est compatible avec tous les niveaux d’optimisation et de configurations de x86 et x64. Toutefois, elle n’est pas compatible avec edit-and-continue, le lien incrémentiel et /RTC.
Prise en charge du vidage sur incident
À compter de Visual Studio 2019 version 16.9, la technologie AddressSanitizer de Microsoft permet l’intégration à l’IDE Visual Studio. La fonctionnalité peut créer un fichier de vidage lorsque le sanitiseur détecte un bogue au moment de l’exécution. Si vous définissez la ASAN_SAVE_DUMPS=MyFileName.dmp variable d’environnement avant d’exécuter votre programme, un fichier de vidage sur incident est créé avec des métadonnées supplémentaires pour un débogage post-mortem efficace des bogues précisément diagnostiqués. Ces fichiers de vidage facilitent l’utilisation étendue de AddressSanitizer pour :
- Test d’ordinateur local
- Tests distribués sur site
- Flux de travail basés sur le cloud pour les tests
Installer AddressSanitizer
Les charges de travail C++ dans Visual Studio Installer installent les bibliothèques AddressSanitizer et l’intégration de l’IDE par défaut. Toutefois, si vous effectuez une mise à niveau à partir d’une version antérieure de Visual Studio 2019, utilisez le programme d’installation pour activer la prise en charge d’ASan après la mise à niveau. Vous pouvez ouvrir le programme d’installation à partir du menu principal Visual Studio en sélectionnant Tools>Get Tools and Features. Choisissez Modify sur votre installation Visual Studio existante à partir du programme d’installation Visual Studio pour accéder à l’écran suivant.
Remarque
Si vous exécutez Visual Studio sur la nouvelle mise à jour, mais que vous n'avez pas installé ASan, vous obtenez une erreur lorsque vous exécutez votre code :
LNK1356 : impossible de trouver la bibliothèque ' clang_rt.asan_dynamic-i386.lib'
Utiliser AddressSanitizer
Commencez à créer vos exécutables avec l'option /fsanitize=address de compilateur à l'aide de l'une de ces méthodes de développement courantes :
- Compilations en ligne de commande
- Système de projet Visual Studio
- Intégration de Visual Studio CMake
Recompilez votre code, puis exécutez votre programme normalement pour exposer de nombreux types de bogues diagnostiqués avec précision. Vous pouvez consulter les problèmes dans le débogueur de l’IDE, la ligne de commande ou le fichier de vidage mémoire.
Microsoft vous recommande d’utiliser AddressSanitizer dans ces trois workflows standard :
Boucle interne du développeur
- Visual Studio - Ligne de commande
- Visual Studio - Système de projet
- Visual Studio - CMake
CI/CD - Intégration continue et livraison continue
- Signalement des erreurs - Fichiers de vidage mémoire AddressSanitizer
Fuzzing - construction avec l'emballage libFuzzer
- Azure OneFuzz
- Ordinateur local
Cet article décrit les informations dont vous avez besoin pour activer les trois flux de travail répertoriés précédemment. Les informations sont spécifiques à l’implémentation d'AddressSanitizer dépendante de la plateforme Windows 10 (et versions ultérieures). Cette documentation complète la documentation de Google, Apple et GCC.
Remarque
La prise en charge est limitée à x86 et x64 sur Windows 10 et versions ultérieures.
Envoyez-nous des commentaires sur ce que vous souhaitez voir dans les versions ultérieures. Vos commentaires nous aident à hiérarchiser d’autres assainisseurs pour l’avenir, tels que /fsanitize=thread, , /fsanitize=leak/fsanitize=memory, , /fsanitize=undefined, ou /fsanitize=hwaddress. Vous pouvez signaler des bogues ici si vous rencontrez des problèmes.
Utiliser AddressSanitizer à partir d’une invite de commandes développeur
Utilisez l’option /fsanitize=address du compilateur dans une invite de commandes pour développeurs pour activer la compilation pour l'environnement d'exécution AddressSanitizer. L’option /fsanitize=address est compatible avec les niveaux d’optimisation C++ ou C existants, par exemple, /Od, /O1, /O2et /O2 /GL. L’option fonctionne avec des CRT statiques et dynamiques (par exemple, /MD, , /MDd/MTet /MTd). Cela fonctionne si vous créez un EXE ou une DLL. Les informations de débogage sont requises pour une mise en forme optimale des piles d’appels. Dans l’exemple suivant, cl /fsanitize=address /Zi est transmis sur la ligne de commande.
Remarque
AddressSanitizer ne prend pas en charge l’optimisation guidée par profil (PGO). AddressSanitizer ne doit pas être utilisé en production.
Les bibliothèques AddressSanitizer (fichiers .lib) sont liées automatiquement. Pour plus d’informations, consultez la référence sur le langage AddressSanitizer, la génération et le débogage.
Exemple : dépassement de mémoire tampon globale de base
// basic-global-overflow.cpp
#include <stdio.h>
int x[100];
int main() {
printf("Hello!\n");
x[100] = 5; // Boom!
return 0;
}
À l’aide d’une invite de commandes de développeur pour Visual Studio 2019, compilez basic-global-overflow.cpp avec /fsanitize=address /Zi.
Lorsque vous exécutez le résultat basic-global-overflow.exe sur la ligne de commande, il crée le rapport d’erreurs mis en forme qui suit.
Considérez les boîtes rouges superposées qui mettent en surbrillance sept éléments d’information clés :
Surbrillances rouges, de haut en bas
- Le bogue de sécurité de la mémoire est un dépassement global de mémoire tampon.
- Il y avait 4 octets (32 bits) stockés en dehors de toute variable définie par l’utilisateur.
- Le stockage a eu lieu dans la fonction
main()définie dans le fichierbasic-global-overflow.cppà la ligne 7. - La variable nommée
xest définie dans basic-global-overflow.cpp sur la ligne 3, en commençant à la colonne 8. - Cette variable
xglobale a une taille de 400 octets. -
L’octet d’ombre exact décrivant l’adresse ciblée par le magasin avait une valeur .
0xf9 - La légende des octets fantômes indique que
0xf9correspond à une zone de remplissage à droite deint x[100].
Remarque
Lorsque AddressSanitizer signale une erreur, le runtime ASan appelle le symbolisateur LLVM pour produire les noms de fonction dans la pile des appels.
Utiliser AddressSanitizer dans Visual Studio
AddressSanitizer est intégré à l’IDE Visual Studio. Pour activer AddressSanitizer pour un projet MSBuild, cliquez avec le bouton droit sur le projet dans Explorateur de solutions et choisissez Propriétés. Dans la Pages de propriétés, sélectionnez Propriétés de configuration>, C/C++>, Général, puis modifiez la propriété Enable AddressSanitizer. Sélectionnez OK pour enregistrer vos modifications.
Pour générer à partir de l’IDE, désactivez les options incompatibles. Pour un projet existant compilé à l’aide /Od (ou mode Débogage), vous devrez peut-être désactiver ces options :
- Désactiver
/ZI(Format des informations de débogage) - Désactiver
/RTC1(vérifications du runtime) - Désactiver
/INCREMENTAL(liaison incrémentielle)
Pour générer et exécuter le débogueur, appuyez sur F5. Une fenêtre d’exception levée s’affiche dans Visual Studio :
Utiliser AddressSanitizer à partir de Visual Studio : CMake
Pour activer AddressSanitizer pour un projet CMake créé pour cibler Windows, procédez comme suit :
Ouvrez le menu déroulant Configurations dans la barre d’outils en haut de l’IDE, puis sélectionnez Gérer les configurations.
Cette action ouvre l'éditeur CMake Project Settings, qui reflète le contenu du fichier
CMakeSettings.jsonde votre project.Choisissez le lien Modifier JSON . Cette sélection bascule l’affichage en JSON brut.
Pour activer AddressSanitizer, ajoutez l’extrait de code suivant au préréglage
"windows-base", à l’intérieur de"configurePresets":."environment": { "CFLAGS": "/fsanitize=address", "CXXFLAGS": "/fsanitize=address" }"configurePresets"ressemble à ceci ensuite :"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 ne fonctionne pas si edit-and-continue est spécifié (
/ZI), qui est activé par défaut pour les nouveaux projets CMake. DansCMakeLists.txt, commentez (préfixe avec#) la ligne qui commence parset(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT". Cette ligne ressemble à ceci :# set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")Utilisez Ctrl+S pour enregistrer ce fichier JSON.
Effacez votre répertoire de cache CMake et reconfigurez en choisissant dans le menu Visual Studio : Supprimer le cache et reconfigurer du projet>. Choisissez Oui lorsque l’invite s’affiche pour effacer votre répertoire de cache et reconfigurer.
Remplacez le contenu du fichier source, par exemple,
CMakeProject1.cpppar le code suivant :// 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; }Choisissez F5 pour recompiler et exécuter sous le débogueur.
Cette capture d’écran montre l’erreur de la construction CMake.
Vidages de mémoire AddressSanitizer
AddressSanitizer inclut des fonctionnalités à utiliser avec des flux de travail cloud et distribués. Cette fonctionnalité permet l’affichage hors connexion d’une erreur AddressSanitizer dans l’IDE. L’erreur est superposée sur votre source, tout comme vous le feriez dans une session de débogage en direct.
Ces fichiers de vidage peuvent entraîner des gains d’efficacité lorsque vous analysez un bogue. Vous n’avez pas besoin de réexécuter, de rechercher des données distantes ou de rechercher une machine hors connexion.
Pour produire un fichier de vidage que vous pouvez afficher dans Visual Studio sur un autre ordinateur à une date ultérieure :
set ASAN_SAVE_DUMPS=MyFileName.dmp
À partir de Visual Studio 16.9, vous pouvez afficher a erreur diagnostiqué avec précision, stockée dans votre fichier *.dmp, en plus de votre code source.
Cette fonctionnalité de vidage sur incident permet des workflows basés sur le cloud ou des tests distribués. Il peut également être utilisé pour enregistrer un bogue détaillé et actionnable dans n’importe quel scénario.
Exemples d’erreurs
AddressSanitizer peut détecter plusieurs types d’erreurs d’utilisation incorrecte de la mémoire. Voici la plupart des erreurs d’exécution signalées lorsque vous exécutez vos fichiers binaires compilés à l’aide de l’option du compilateur AddressSanitizer (/fsanitize=address) :
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
Pour plus d’informations sur les exemples, consultez les exemples d’erreur AddressSanitizer.
Différences avec Clang 12.0
MSVC diffère actuellement de Clang 12.0 dans deux domaines fonctionnels :
- stack-use-after-scope : ce paramètre est activé par défaut et ne peut pas être désactivé.
-
stack-use-after-return : cette fonctionnalité nécessite une option de compilateur supplémentaire et n’est pas disponible uniquement en définissant
ASAN_OPTIONS.
Ces décisions ont été prises pour réduire la matrice de test nécessaire pour fournir cette première version.
Les fonctionnalités susceptibles d’entraîner des faux positifs dans Visual Studio 2019 16.9 n’ont pas été incluses. Cette discipline a imposé une intégrité de test efficace nécessaire lorsque l'on considère l'interopérabilité avec plusieurs décennies de code existant. D’autres fonctionnalités peuvent être prises en compte dans les versions ultérieures :
- Ordre d’initialisation Fiasco
- Intra Object Overflow
- Dépassement de capacité du conteneur
- Soustraction/comparaison du pointeur
Pour plus d’informations, consultez Building for AddressSanitizer avec MSVC.
Documentation du secteur
Une documentation complète existe pour ces implémentations dépendantes de la langue et de la plateforme de la technologie AddressSanitizer.
Ce document séminal sur l'AddressSanitizer (externe) décrit l’implémentation.