AddressSanitizer

Vue d’ensemble

Les langages C &C++ sont puissants, mais peuvent souffrir d’une classe de bogues qui affectent la correction du programme et la sécurité du programme. À compter de Visual Studio 2019 version 16.9, le compilateur Microsoft C/C++ (MSVC) et l’IDE prennent en charge le nettoyage AddressSanitizer . AddressSanitizer (ASan) est une technologie de compilateur et d’exécution qui expose de nombreux bogues difficiles à trouver avec zéro faux positifs :

Utilisez AddressSanitizer pour réduire votre temps passé à :

  • Exactitude de base
  • 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.

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. La nouvelle option est compatible avec tous les niveaux d’optimisation et de configurations de x86 et x64. Toutefois, elle n’est pas compatible avec la liaison incrémentielle et la modification/RTC et la poursuite.

À compter de Visual Studio 2019 version 16.9, la technologie AddressSanitizer de Microsoft permet l’intégration à l’IDE Visual Studio. La fonctionnalité peut éventuellement créer un fichier de vidage sur incident lorsque l’assainissement trouve 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 diagnostiqués avec précision. Ces fichiers de vidage facilitent l’utilisation étendue de AddressSanitizer pour :

  • Test d’ordinateur local
  • Tests distribués locaux
  • 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 de Visual Studio via Tools Get Tools>and Features... Choisissez Modifier sur votre installation existante de Visual Studio à partir de Visual Studio Installer pour accéder à l’écran suivant.

Capture d’écran de Visual Studio Installer. Le composant AddressSanitizer C++, sous la section Facultative, est mis en surbrillance.

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 du compilateur à l’aide /fsanitize=address de l’une de ces méthodes de développement courantes :

  • Builds de ligne de commande
  • Système de projet Visual Studio
  • Intégration de Visual Studio CMake

Recompilez, puis exécutez normalement votre programme. Cette génération de code expose de nombreux types de bogues diagnostiqués avec précision. Ces erreurs sont signalées de trois façons : dans l’IDE du débogueur, sur la ligne de commande ou stockées dans un nouveau type de fichier de vidage pour un traitement précis hors ligne.

Microsoft vous recommande d’utiliser AddressSanitizer dans ces trois workflows standard :

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 windows 10 (et ultérieure) dépendante de la plateforme de AddressSanitizer. Cette documentation complète la documentation excellente de Google, Apple et GCC déjà publiée.

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 développeur pour activer la compilation pour le runtime AddressSanitizer. L’option /fsanitize=address est compatible avec tous les niveaux d’optimisation C++ ou C existants (par exemple, , /Od, /O1/O2, /O2 /GLet PGO). 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.

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 développeur pour Visual Studio 2019, compilez main.cpp à l’aide de /fsanitize=address /Zi

Capture d’écran d’une invite de commandes montrant la commande à compiler avec les options AddressSanitizer. La commande est : 'cl main.cpp -faanitize-address /Zi'.

Lorsque vous exécutez le résultat main.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 :

Capture d’écran du débogueur montrant une erreur de dépassement globale de base.

Il existe sept points forts rouges identifiant les éléments clés d’information dans le rapport d’erreurs. Ils mappent à la liste numérotée qui suit cette capture d’écran. Les zones numérotées mettent en surbrillance le texte suivant : 1) global-buffer-overflow 2) WRITE de taille 4 3) basic-global-overflow.cpp 7 4) à droite de la variable globale 'x' définie dans 'basic-global-overflow.cpp :3:8' 5) de taille 400 6) 00 00[f9]f9 f9 7) Box se trouve dans la zone de légende d’octets d’ombre et contient la zone de légende globale : f9

Surbrillances rouges, de haut en bas

  1. Le bogue de sécurité de la mémoire est un dépassement global de mémoire tampon.
  2. Il y avait 4 octets (32 bits) stockés en dehors de toute variable définie par l’utilisateur.
  3. Le magasin a eu lieu dans la fonction main() définie dans le fichier basic-global-overflow.cpp à la ligne 7.
  4. La variable nommée x est définie dans basic-global-overflow.cpp sur la ligne 3, en commençant à la colonne 8
  5. Cette variable x globale est de taille de 400 octets
  6. L’octet d’ombre exact décrivant l’adresse ciblée par le magasin avait une valeur de0xf9
  7. La légende d’octets d’ombre indique qu’il s’agit 0xf9 d’une zone de remplissage à droite de int x[100]

Remarque

Les noms de fonction dans la pile des appels sont générés via le symbolisateur LLVM appelé par le runtime lors de l’erreur.

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 boîte de dialogue 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.

Capture d’écran de la boîte de dialogue Pages de propriétés montrant la propriété Enable AddressSanitizer.

Pour générer à partir de l’IDE, désactivez les options incompatibles. Pour un projet existant compilé à l’aide /Od (ou en mode Débogage), vous devrez peut-être désactiver ces options :

Pour générer et exécuter le débogueur, appuyez sur F5. Une fenêtre levée d’exception s’affiche dans Visual Studio :

Capture d’écran du débogueur montrant une erreur globale de dépassement de mémoire tampon.

Utiliser AddressSanitizer à partir de Visual Studio : CMake

Pour activer AddressSanitizer pour un projet CMake créé pour cibler Windows, procédez comme suit :

  1. Ouvrez la liste déroulante Configurations dans la barre d’outils en haut de l’IDE, puis sélectionnez Gérer les configurations.

    Capture d’écran de la liste déroulante de configuration CMake. Il affiche des options telles que le débogage x64, la version x64, et ainsi de suite. En bas de la liste, Gérer les configurations... est mis en surbrillance.

    Cela ouvre l’éditeur paramètres du projet CMake, qui reflète le contenu du fichier de CMakeSettings.json votre projet.

  2. Choisissez le lien Modifier JSON dans l’éditeur. Cette sélection bascule l’affichage en JSON brut.

  3. Ajoutez l’extrait de code suivant à la présélection, à l’intérieur "windows-base" "configurePresets": pour activer le nettoyage d’adresse :

    "environment": {
      "CFLAGS": "/fsanitize=address",
      "CXXFLAGS": "/fsanitize=address"
    }
    

    "configurePresets" ressemble à ceci, par la suite :

        "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"
            }
          },
    
  4. Le nettoyage d’adresse ne fonctionne pas si la modification et la poursuite sont spécifiées (/ZI), qui est activée par défaut pour les nouveaux projets CMake. Dans CMakeLists.txt, commentez (préfixe avec #) la ligne qui commence par set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT". Cette ligne ressemble à ceci, par la suite :

    # set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
    
  5. Entrez Ctrl+S pour enregistrer ce fichier JSON

  6. 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.

  7. Remplacez le contenu du fichier source (par exemple, CMakeProject1.cpp) par les éléments suivants :

    // 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;
    }
    
  8. Choisissez F5 pour recompiler et exécuter sous le débogueur.

    Cette capture d’écran capture l’erreur à partir de la build CMake.

    Capture d’écran d’une exception qui indique : Address Sanitizer Error : Global buffer overflow. En arrière-plan, la sortie du désinfecteur d’adresse est visible dans la fenêtre de commande.

Vidages sur incident addressSanitizer

Nous avons introduit de nouvelles fonctionnalités dans AddressSanitizer pour une utilisation 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 nouveaux fichiers de vidage peuvent entraîner une efficacité lors de l’analyse d’un bogue. Vous n’avez pas besoin de réexécuter, de rechercher des données distantes ou de rechercher une machine hors ligne.

Pour produire un nouveau type de fichier de vidage qui peut être affiché dans Visual Studio sur un autre ordinateur à une date ultérieure :

set ASAN_SAVE_DUMPS=MyFileName.dmp

À compter de Visual Studio 16.9, vous pouvez afficher une erreur précisément diagnostiqué, stockée dans votre *.dmp fichier, en plus de votre code source.

Cette nouvelle fonctionnalité de vidage sur incident permet des flux de travail 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) :

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 appliqué l’intégrité efficace des tests nécessaires lors de l’interopérabilité avec des décennies de code existant. D’autres fonctionnalités peuvent être prises en compte dans les versions ultérieures :

Pour plus d’informations, consultez Building for AddressSanitizer avec MSVC.

Documentation du secteur existant

Une documentation complète existe déjà pour ces implémentations dépendantes de la langue et de la plateforme de la technologie AddressSanitizer.

Ce document séminal sur addressSanitizer (externe) décrit l’implémentation.

Voir aussi

Résoudre les problèmes connus liés à AddressSanitizer
Référence de build et de langage AddressSanitizer
Informations de référence sur le runtime AddressSanitizer
Octets d’ombre AddressSanitizer
Test cloud ou distribué AddressSanitizer
Intégration du débogueur AddressSanitizer
Exemples d’erreur AddressSanitizer