Analyse de vidage sur plantage
Tous les bogues ne peuvent pas être trouvés avant la publication, ce qui signifie que tous les bogues qui lèvent des exceptions peuvent être trouvés avant la mise en production. 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 traitement 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
- Sécurité des threads
- Écriture d’un minidump avec du code
- Utilisation de Dumpchk.exe
- Analyse d’un minidump
- Résumé
Écriture d’un minidump
Les options de base pour l’écriture d’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 (Rapport d'erreurs Windows). Les développeurs peuvent accéder à ces minidumps via le programme d’application de bureau Windows.
L’utilisation de Rapport d'erreurs Windows nécessite :
- Développeurs pour signer leurs applications à l’aide d’Authenticode
- Les applications ont une ressource VERSIONINFO valide dans chaque exécutable et DLL
Si vous implémentez une routine personnalisée pour les exceptions non gérées, vous êtes vivement invité à utiliser la fonction ReportFault dans le gestionnaire d’exceptions pour envoyer également un minidump automatisé à Rapport d'erreurs Windows. La fonction ReportFault gère tous les problèmes de connexion et d’envoi du minidump à Rapport d'erreurs Windows. Ne pas envoyer de minidumps à Rapport d'erreurs Windows enfreint les exigences des Jeux pour Windows.
Pour plus d’informations sur le fonctionnement de Rapport d'erreurs Windows, consultez Fonctionnement de 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ébogage , cliquez sur Enregistrer le vidage sous pour enregistrer une copie d’un vidage. L’utilisation d’un vidage enregistré localement n’est qu’une option pour les tests et le débogage internes.
Ajoutez du code à votre projet. Ajoutez la fonction MiniDumpWriteDump et le code de gestion des exceptions appropriés 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’est pas thread-safe. Par conséquent, tout programme qui utilise MiniDumpWriteDump doit synchroniser tous les threads avant de tenter 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 est à la hauteur du développeur ; Toutefois, pour éviter les collisions de noms de fichiers, il est recommandé de générer le nom de fichier à partir du nom et du numéro de version de l’application, du processus et des ID 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 incombe 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 d’accès du répertoire désigné pour les fichiers temporaires. L’utilisation de ce répertoire fonctionne même avec des comptes d’utilisateur avec des privilèges minimum et empêche également le minidump de prendre de l’espace disque après 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 que vous puissiez déboguer une ancienne version du produit, si nécessaire. Vous devez également prendre des mesures pour maintenir les 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 :
- Sur le côté gauche de la page de propriétés du projet, cliquez sur C/C++. Par défaut, cela affiche les paramètres généraux . Sur le côté droit de la page de propriétés du projet, définissez Debug Information Format to Program Database (/Zi).
- Sur le côté gauche de la page de propriétés, développez l’É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 des informations de débogagesur Oui (/DEBUG).
- Cliquez sur Optimisation et définissez références aux données non référencées (/OPT:REF) Eliminate.
- Définissez l’option 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 dans le CD du produit Windows XP et peut être installé sur le lecteur système\Program Files\Support Tools\ en exécutant Setup.exe dans le dossier Support\Tools\ du cd-ROM 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 de Windows Outils de débogage sur Windows Hardware Developer Central.
Analyse d’un minidump
L’ouverture d’un minidump pour l’analyse est aussi simple que la création.
Pour analyser un minidump
- Ouvrez Visual Studio.
- Dans le menu Fichier, cliquez sur Ouvrir Project.
- Définissez fichiers de type sur Fichiers de vidage, accédez au fichier de vidage, sélectionnez-le, puis cliquez sur Ouvrir.
- Exécutez le débogueur.
Le débogueur crée un processus simulé. Le processus simulé est arrêté à l’instruction qui a provoqué 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 pointer vers le serveur de symboles publics Microsoft.
Pour définir un chemin d’accès au serveur de symboles Microsoft
- Dans le menu Débogage , cliquez sur Options.
- Dans la boîte de dialogue Options , ouvrez le nœud Débogage , puis cliquez sur Symboles.
- Veillez à rechercher les emplacements ci-dessus uniquement lorsque les symboles sont chargés manuellement , sauf si vous souhaitez charger manuellement des symboles lorsque vous déboguez.
- 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 du cache 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 du cache fait référence à un répertoire sur l’ordinateur distant.
- Cliquez sur OK.
- É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 Windows Outils de débogage, consultez Windows Outils de débogage sur Windows Hardware Developer Central.
Après avoir installé Windows Outils de débogage, vous devez entrer le chemin du symbole dans WinDbg.
Pour entrer un chemin de symbole dans WinDbg
Dans le menu Fichier , cliquez sur Chemin du symbole.
Dans la fenêtre Chemin de recherche de symboles , entrez les éléments suivants :
"srv\*c:\\cache\*https://msdl.microsoft.com/download/symbols;"
Utilisation de Copy-Protection Tools avec Minidumps
Les développeurs doivent également savoir comment leur schéma de protection contre la copie peut affecter le minidump. La plupart des schémas de protection contre la copie ont leurs propres outils de déscramble, et il incombe au développeur d’apprendre à utiliser ces outils avec MiniDumpWriteDump.
Résumé
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 collection 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 basé sur C++et doit être considérée comme faisant partie du processus de stabilité de tout projet.