Analyse de vidage sur plantage

Tous les bogues ne sont pas trouvés avant la publication, ce qui signifie que tous les bogues qui lèvent des exceptions ne peuvent pas être trouvés avant la publication. Heureusement, Microsoft a inclus dans le KIT de développement logiciel (SDK) de plateforme une fonction pour aider les développeurs à collecter des informations sur les exceptions découvertes par les utilisateurs. La fonction MiniDumpWriteDump écrit les informations de vidage sur incident nécessaires dans un fichier sans enregistrer l’espace de processus entier. Ce fichier d’informations de vidage sur incident est appelé minidump. Cet article technique fournit des informations sur l’écriture et l’utilisation d’un minidump.

Écriture d’un minidump

Les options de base pour écrire un minidump sont les suivantes :

  • Ne rien faire. Windows génère automatiquement un minidump chaque fois qu’un programme lève une exception non gérée. La génération automatique d’un minidump est disponible depuis Windows XP. Si l’utilisateur l’autorise, le minidump est envoyé à Microsoft, et non au développeur, via Rapport d'erreurs Windows (WER). Les développeurs peuvent accéder à ces minidumps via le Programme d’application de bureau Windows.

    L’utilisation de WER nécessite :

    • Les développeurs doivent signer leurs applications à l’aide d’Authenticode
    • Les applications ont une ressource VERSIONINFO valide dans chaque fichier exécutable et chaque DLL

    Si vous implémentez une routine personnalisée pour les exceptions non prises en charge, il est vivement recommandé d’utiliser la fonction ReportFault dans le gestionnaire d’exceptions pour envoyer également un minidump automatisé à WER. La fonction ReportFault gère tous les problèmes de connexion à et d’envoi du minidump à WER. Le fait de ne pas envoyer de minidumps à WER ne respecte pas les exigences de Games pour Windows.

    Pour plus d’informations sur le fonctionnement de WER, consultez Fonctionnement Rapport d'erreurs Windows. Pour obtenir une explication des détails de l’inscription, consultez Présentation de Rapport d'erreurs Windows sur la zone ISV de MSDN.

  • Utilisez un produit du système d’équipe Microsoft Visual Studio. Dans le menu Déboguer , cliquez sur Enregistrer le vidage sous pour enregistrer une copie d’un vidage. L’utilisation d’un vidage enregistré localement est uniquement une option pour le test et le débogage internes.

  • Ajoutez du code à votre projet. Ajoutez la fonction MiniDumpWriteDump et le code de gestion des exceptions approprié pour enregistrer et envoyer un minidump directement au développeur. Cet article montre comment implémenter cette option. Toutefois, notez que MiniDumpWriteDump ne fonctionne pas avec du code managé et n’est disponible que sur Windows XP, Windows Vista, Windows 7.

Sécurité des threads

MiniDumpWriteDump fait partie de la bibliothèque DBGHELP. Cette bibliothèque n’étant pas thread-safe, tout programme qui utilise MiniDumpWriteDump doit synchroniser tous les threads avant d’essayer d’appeler MiniDumpWriteDump.

Écriture d’un minidump avec du code

L’implémentation réelle est simple. Voici un exemple simple d’utilisation de MiniDumpWriteDump.

#include <dbghelp.h>
#include <shellapi.h>
#include <shlobj.h>

int GenerateDump(EXCEPTION_POINTERS* pExceptionPointers)
{
    BOOL bMiniDumpSuccessful;
    WCHAR szPath[MAX_PATH]; 
    WCHAR szFileName[MAX_PATH]; 
    WCHAR* szAppName = L"AppName";
    WCHAR* szVersion = L"v1.0";
    DWORD dwBufferSize = MAX_PATH;
    HANDLE hDumpFile;
    SYSTEMTIME stLocalTime;
    MINIDUMP_EXCEPTION_INFORMATION ExpParam;

    GetLocalTime( &stLocalTime );
    GetTempPath( dwBufferSize, szPath );

    StringCchPrintf( szFileName, MAX_PATH, L"%s%s", szPath, szAppName );
    CreateDirectory( szFileName, NULL );

    StringCchPrintf( szFileName, MAX_PATH, L"%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp", 
               szPath, szAppName, szVersion, 
               stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, 
               stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, 
               GetCurrentProcessId(), GetCurrentThreadId());
    hDumpFile = CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, 
                FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);

    ExpParam.ThreadId = GetCurrentThreadId();
    ExpParam.ExceptionPointers = pExceptionPointers;
    ExpParam.ClientPointers = TRUE;

    bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), 
                    hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);

    return EXCEPTION_EXECUTE_HANDLER;
}


void SomeFunction()
{
    __try
    {
        int *pBadPtr = NULL;
        *pBadPtr = 0;
    }
    __except(GenerateDump(GetExceptionInformation()))
    {
    }
}

Cet exemple illustre l’utilisation de base de MiniDumpWriteDump et les informations minimales nécessaires pour l’appeler. Le nom du fichier de vidage appartient au développeur ; toutefois, pour éviter les collisions de noms de fichier, il est recommandé de générer le nom du fichier à partir du nom et du numéro de version de l’application, des ID de processus et de thread, ainsi que de la date et de l’heure. Cela permet également de conserver les minidumps regroupés par application et version. Il appartient au développeur de décider de la quantité d’informations utilisées pour différencier les noms de fichiers minidump.

Notez que le nom du chemin d’accès dans l’exemple précédent a été généré en appelant la fonction GetTempPath pour récupérer le chemin du répertoire désigné pour les fichiers temporaires. L’utilisation de ce répertoire fonctionne même avec les comptes d’utilisateur les moins privilégiés, et elle empêche également le minidump de prendre de l’espace sur le disque dur une fois qu’il n’est plus nécessaire.

Si vous archivez le produit pendant votre processus de génération quotidien, veillez également à inclure des symboles pour la build afin de pouvoir déboguer une ancienne version du produit, si nécessaire. Vous devez également prendre des mesures pour maintenir des optimisations complètes du compilateur tout en générant des symboles. Pour ce faire, ouvrez les propriétés de votre projet dans l’environnement de développement et, pour la configuration de mise en production, procédez comme suit :

  1. Sur le côté gauche de la page de propriétés du projet, cliquez sur C/C++. Par défaut, les paramètres généraux sont affichés. Sur le côté droit de la page de propriétés du projet, définissez Debug Information Formatsur Program Database (/Zi).
  2. Sur le côté gauche de la page de propriétés, développez Éditeur de liens, puis cliquez sur Débogage. Sur le côté droit de la page de propriétés, définissez Générer les informations de débogage sur Oui (/DEBUG).
  3. Cliquez sur Optimisation, puis définissez Références à Eliminate Unreferenced Data (/OPT:REF).
  4. Définissez Activer le pliage COMDAT pour supprimer les COMDAT redondants (/OPT:ICF).

MSDN contient des informations plus détaillées sur la structure MINIDUMP_EXCEPTION_INFORMATION et la fonction MiniDumpWriteDump .

Utilisation de Dumpchk.exe

Dumpchk.exe est un utilitaire de ligne de commande qui peut être utilisé pour vérifier qu’un fichier de vidage a été créé correctement. Si Dumpchk.exe génère une erreur, le fichier de vidage est endommagé et ne peut pas être analysé. Pour plus d’informations sur l’utilisation de Dumpchk.exe, consultez Comment utiliser Dumpchk.exe pour vérifier un fichier de vidage de mémoire.

Dumpchk.exe est inclus sur le CD du produit Windows XP et peut être installé sur lecteur système\Program Files\Support Tools\ en exécutant Setup.exe dans le dossier Support\Tools\ sur le CD du produit Windows XP. Vous pouvez également obtenir la dernière version de Dumpchk.exe en téléchargeant et en installant les outils de débogage disponibles à partir des Outils de débogage Windows sur Windows Hardware Developer Central.

Analyse d’un Minidump

L’ouverture d’un minidump pour l’analyse est aussi simple que d’en créer un.

Pour analyser un minidump

  1. Ouvrez Visual Studio.
  2. Dans le menu Fichier , cliquez sur Ouvrir le projet.
  3. Définissez Fichiers de type sur Fichiers de vidage, accédez au fichier de vidage, sélectionnez-le, puis cliquez sur Ouvrir.
  4. Exécutez le débogueur.

Le débogueur crée un processus simulé. Le processus simulé sera arrêté à l’instruction à l’origine de l’incident.

Utilisation du serveur de symboles publics Microsoft

Pour obtenir la pile pour les incidents au niveau du pilote ou du système, il peut être nécessaire de configurer Visual Studio pour qu’il pointe vers le serveur de symboles publics Microsoft.

Pour définir un chemin d’accès au serveur de symboles Microsoft

  1. Dans le menu Déboguer , cliquez sur Options.
  2. Dans la boîte de dialogue Options , ouvrez le nœud Débogage , puis cliquez sur Symboles.
  3. Assurez-vous que rechercher les emplacements ci-dessus uniquement lorsque les symboles sont chargés manuellement n’est pas sélectionné, sauf si vous souhaitez charger les symboles manuellement lorsque vous déboguez.
  4. Si vous utilisez des symboles sur un serveur de symboles distant, vous pouvez améliorer les performances en spécifiant un répertoire local vers lequel les symboles peuvent être copiés. Pour ce faire, entrez un chemin d’accès pour les symboles de cache à partir du serveur de symboles vers ce répertoire. Pour vous connecter au serveur de symboles publics Microsoft, vous devez activer ce paramètre. Notez que si vous déboguez un programme sur un ordinateur distant, le répertoire de cache fait référence à un répertoire sur l’ordinateur distant.
  5. Cliquez sur OK.
  6. Étant donné que vous utilisez le serveur de symboles publics Microsoft, une boîte de dialogue Contrat de licence utilisateur final s’affiche. Cliquez sur Oui pour accepter le contrat et télécharger les symboles dans votre cache local.

Débogage d’un Minidump avec WinDbg

Vous pouvez également utiliser WinDbg, un débogueur qui fait partie des outils de débogage Windows, pour déboguer un minidump. WinDbg vous permet de déboguer sans avoir à utiliser Visual Studio. Pour télécharger les outils de débogage Windows, consultez Outils de débogage Windows sur Windows Hardware Developer Central.

Après avoir installé les outils de débogage Windows, vous devez entrer le chemin du symbole dans WinDbg.

Pour entrer un chemin de symbole dans WinDbg

  1. Dans le menu Fichier , cliquez sur Chemin du symbole.

  2. Dans la fenêtre Chemin de recherche de symboles , entrez les éléments suivants :

    "srv\*c:\\cache\*https://msdl.microsoft.com/download/symbols;"

Utilisation des outils Copy-Protection avec Minidumps

Les développeurs doivent également savoir comment leur schéma de protection contre la copie peut affecter le minidump. La plupart des systèmes de protection contre la copie ont leurs propres outils de désagrément, et c’est au développeur d’apprendre à utiliser ces outils avec MiniDumpWriteDump.

Récapitulatif

La fonction MiniDumpWriteDump peut être un outil extrêmement utile pour collecter et résoudre des bogues après la publication du produit. L’écriture d’un gestionnaire d’exceptions personnalisé qui utilise MiniDumpWriteDump permet au développeur de personnaliser la collecte d’informations et d’améliorer le processus de débogage. La fonction est suffisamment flexible pour être utilisée dans n’importe quel projet C++et doit être considérée comme faisant partie du processus de stabilité de tout projet.