Utiliser l’utilitaire PageHeap pour détecter les erreurs de mémoire dans un projet Visual C++

Cet article explique comment utiliser l’utilitaire PageHeap pour détecter les erreurs de mémoire dans Microsoft Visual C++ projets. Les informations contenues dans cet article s’appliquent uniquement au code Visual C++ non managé.

Version d’origine du produit : Visual C++
Numéro de la base de connaissances d’origine : 264471

Résumé

L’utilitaire PageHeap peut être activé pour les applications afin que toutes les mallocallocations , newet heapAlloc soient automatiquement surveillées pour détecter les erreurs de mémoire.

PageHeap1 est un projet Visual C++ avec plusieurs types d’erreurs de mémoire. Pour activer PageHeap sur cet exemple d’application, tapez le contenu suivant à partir de la ligne de commande :

pageheap /enable pgh.exe 0x01

Ensuite, tapez le contenu suivant :

pageheap

Remarque

Nom de l’application que PageHeap surveille.

Pour de nombreuses applications, 0x01 est le seul indicateur dont vous avez besoin. Vous pouvez obtenir plus d’informations sur son utilisation en exécutant PageHeap avec l’indicateur de point d’interrogation (/?) à partir de la ligne de commande.

Fonctionnement de PageHeap

PageHeap retourne un pointeur vers la mémoire allouée sur les limites de 8 octets. La fin du pointeur retourné est suivie de 0 à 7 octets de protection (selon la taille demandée, 0 octet à 7 octets sont ajoutés pour arrondir la taille de la requête à une limite de 8 octets), suivi d’une page mémoire marquée PAGE_NOACCESS (pour plus d’informations, voir VirtualAlloc). Par exemple :

char * p;
p = new char[5];

PageHeap retourne un pointeur vers les 5 octets plus trois octets de protection pour un total de 8 octets, par exemple..... XXX. Si la taille d’allocation de mémoire est un multiple de huit, aucun octet de protection n’est ajouté au pointeur retourné.

Si la fin de l’allocation est remplacée, les octets de protection changent et PageHeap provoque une erreur de violation d’accès lorsque la mémoire est libérée. Si l’application lit ou écrit au-delà de l’allocation (y compris les octets de protection), elle génère une erreur de violation d’accès instantanée.

Guide pratique pour utiliser l’exemple PageHeap1

  1. Générez le projet pgh et exécutez le pgh.exe.

    Remarque

    Vous devez effectuer une build de mise en production pour que PageHeap fonctionne avec new ou malloc.

    Lancez le PageHeap1.exe. Une boîte de dialogue s’affiche.

  2. Dans la boîte de dialogue, vous pouvez voir une zone de texte, une zone de case activée bad alloc/Free et trois paires de boutons, new & delete, PageAlloc & Heap Free et COM new & COM Delete. TextBox prend la taille de mémoire que vous souhaitez allouer. Si la zone Alloc/Free case activée est sélectionnée, chaque type d’allocation (nouveau, PageAlloc et COM new) alloue de la mémoire, puis écrit au-delà de l’allocation. Si l’option Alloc incorrecte n’est pas cochée, aucun remplacement de mémoire ne se produit.

    Le nouveau bouton teste l’opérateur new , le bouton PageAlloc teste HeapAlloc. Le nouveau COM n’utilise CoTaskMemAlloc pas, mais appelle plutôt dans une bibliothèque de liens dynamiques COM (DLL) qui appelle newsimplement . Pour tester COM new, vous devez inscrire r1LeakMemMod.dll ou générer le projet r1LeakMemMod.

    Vous pouvez utiliser une bibliothèque DLL d’exécution pour que PageHeap fonctionne. (À partir de l’environnement de développement intégré (IDE) Visual C++, projets>Paramètres>C++>Catégorie : Génération de> codeUtiliser la bibliothèque d’exécution).

  3. Après avoir cochant la case Alloc/Free incorrect, si la taille d’allocation de mémoire est de 5 octets, sélectionnez le nouveau bouton, 5 octets de mémoire sont alloués et 0 est écrit dans le sixième octet. L’écriture sur le sixième octet est un remplacement de mémoire illégal, mais il se produit sur un octet de garde afin que PageHeap ne détecte pas cette erreur tant que la mémoire n’est pas supprimée. Lorsque vous sélectionnez le bouton Supprimer, PageHeap détecte le remplacement et une boîte de message d’erreur semblable à l’exemple suivant s’affiche :

    Point d’arrêt de l’exception Un point d’arrêt a été atteint. (0x80000003) s’est produit dans l’application à l’emplacement 0x77f9f9df.

    Si visual C++ est spécifié comme débogueur juste-à-temps (JIT), vous pouvez sélectionner le bouton Annuler et déboguer dans le code.

    Si vous modifiez la taille d’allocation sur 8 (ou un multiple de 8), la sélection des boutons nouveau, pageAlloc ou COM New génère une erreur de violation d’accès instantanée, car vous avez écrit dans une adresse sans accès. (c’est-à-dire que vous n’avez pas besoin de supprimer la mémoire pour détecter l’erreur).

Remarque

  1. Limitations : PageHeap ne peut trouver que les erreurs de mémoire de la malloc famille (d’où l’opérateur newC++ ) et heapAlloc. De nombreuses applications utilisent des allocateurs personnalisés et PageHeap ne peut pas intercepter ces allocations.
  2. Lorsque vous avez terminé de tester une application, exécutez pageheap /disable <appName> à partir de la ligne de commande pour désactiver PageHeap pour cette application.
  3. Les applications prenant en charge PageHeap peuvent consommer beaucoup plus de mémoire que la même application sans PageHeap activé. Vous devrez peut-être augmenter votre fichier d’échange pour répondre à l’augmentation de la demande de mémoire.

Vous pouvez télécharger Pageheap1vcnet.exe ici. Pour plus d’informations sur le téléchargement des fichiers de support Microsoft, consultez Comment obtenir des fichiers de support Microsoft à partir de services en ligne.

Microsoft a analysé ce fichier à la recherche de virus. Microsoft a utilisé le logiciel de détection de virus le plus actuel disponible à la date de publication du fichier. Le fichier est stocké sur des serveurs à sécurité renforcée qui permettent d’empêcher toute modification non autorisée du fichier.