Modifier

Forum Aux Questions sur le débogage du code natif

Comment puis-je déboguer les violations d’accès quand mon programme fonctionne hors du débogueur Visual Studio ?

Paramétrez l’option Débogage juste-à-temps et exécutez votre programme de façon autonome jusqu’à ce que la violation d’accès se produise. Dans la boîte de dialogue Violation d’accès, vous pouvez ensuite cliquer sur Annuler afin de démarrer le débogueur.

Comment puis-je déboguer une violation d’accès C++ ?

Si vous obtenez une violation d’accès sur une ligne de code qui déréférence plusieurs pointeurs, il peut être difficile de trouver le pointeur à l’origine de la violation d’accès. Dans Visual Studio, la boîte de dialogue d’exception nomme de manière explicite le pointeur à l’origine de la violation d’accès.

Par exemple, le code suivant doit générer une violation d’accès :

#include <iostream>
using namespace std;

class ClassC {
public:
  void printHello() {
    cout << "hello world";
  }
};

class ClassB {
public:
  ClassC* C;
  ClassB() {
    C = new ClassC();
  }
};

class ClassA {
public:
  ClassB* B;
  ClassA() {
    // Uncomment to fix
    // B = new ClassB();
  }
};

int main() {
  ClassA* A = new ClassA();
  A->B->C->printHello();

}

Si vous exécutez ce code dans Visual Studio, la boîte de dialogue d’exception suivante doit s’afficher :

Screenshot of a Microsoft Visual Studio exception dialog, showing a read access violation for 'A->B was nullptr'. The Break button is selected.

Si vous n’arrivez pas à déterminer la raison pour laquelle le pointeur a provoqué une violation d’accès, tracez le code pour vérifier que le pointeur à l’origine du problème a été correctement assigné. S’il s’agit d’un paramètre, vérifiez qu’il soit passé correctement et qu’une copie superficielle n’est pas accidentellement créée. Vérifiez ensuite que les valeurs ne sont pas modifiées de manière non intentionnelle à un endroit du programme. Pour cela, créez un point d’arrêt sur variable pour le pointeur en question pour vous assurer qu’il n’est pas en cours de modification autre part dans le programme. Pour plus d’informations sur les points d’arrêt sur variable, consultez la section consacrée à ce sujet dans Using Breakpoints.

Comment puis-je savoir si mes pointeurs endommagent une adresse mémoire ?

Vérifier l’altération du tas. La plus grande partie de l’altération de la mémoire est provoquée par l’altération du tas. Servez-vous de l'utilitaire Global Flags (gflags.exe) ou de pageheap.exe. Consultez /windows-hardware/drivers/debugger/gflags-and-pageheap.

Pour rechercher la modification de l’adresse mémoire :

  1. Définissez un point d'arrêt sur variable à l'adresse 0x00408000. Consultez Définir un point d’arrêt de modification de données (C++ natif uniquement).

  2. Quand vous atteignez le point d’arrêt, utilisez la fenêtre Mémoire pour afficher le contenu de la mémoire à partir de l’adresse 0x00408000. Pour plus d’informations, consultez Fenêtres Mémoire.

Comment puis-je savoir d’où provient une valeur de paramètre incorrecte ?

Pour résoudre ce problème :

  1. Définissez un point d'arrêt d'emplacement au début de la fonction.

  2. Cliquez avec le bouton droit sur le point d’arrêt et sélectionnez Condition.

  3. Dans la boîte de dialogue Condition de point d’arrêt, cochez la case Condition. Consultez Points d’arrêt avancés.

  4. Entrez une expression, telle que Var==3, dans la zone de texte, où Var est le nom du paramètre qui contient la valeur incorrecte et où 3 correspond à la valeur incorrecte passée.

  5. Activez la case d’option est true, puis cliquez sur le bouton OK.

  6. Réexécutez le programme. Le point d'arrêt provoque l'arrêt du programme au début de la fonction lorsque la valeur du paramètre Var est 3.

  7. Utilisez la fenêtre Pile des appels pour rechercher la fonction d'appel et naviguer jusqu'à son code source. Pour plus d’informations, consultez Guide pratique pour utiliser la fenêtre Pile des appels.

Lorsque j’appelle une fonction des centaines de fois, comment puis-je savoir quel appel a échoué ?

Exemple : Mon programme échoue lors de l’appel à une certaine fonction, CnvtV. Mais cet échec survient probablement après plusieurs centaines d'appels à la fonction par le programme. Si je définis un point d'arrêt d'emplacement sur CnvtV, le programme s'arrête à chaque appel de cette fonction, ce que je veux éviter. J'ignore quelles conditions ont provoqué l'échec de l'appel et je ne peux donc pas définir un point d'arrêt conditionnel. Que puis-je faire ?

Vous pouvez définir un point d’arrêt sur la fonction en affectant au champ Nombre d’accès une valeur très élevée que vous ne risquez pas d’atteindre. Dans le cas présent, vous estimez que la fonction CnvtV est appelée plusieurs centaines de fois ; vous affectez par conséquent à Nombre d’accès la valeur 1 000 ou une valeur supérieure. Exécutez ensuite le programme et patientez jusqu'à l'échec de l'appel. Lorsqu'il échoue, ouvrez la fenêtre Points d'arrêt et examinez la liste des points d'arrêt. Le point d'arrêt que vous avez défini sur CnvtV apparaît, suivi du nombre d'accès et du nombre d'itérations restantes :

CnvtV(int) (no condition) when hit count is equal to 1000 (currently 101)

Vous savez à présent que la fonction a échoué au 101e appel. Si vous réinitialisez le point d'arrêt avec un nombre d'accès égal à 101, puis que vous réexécutez le programme, ce dernier s'arrête au niveau de l'appel à CnvtV qui a provoqué son échec.

Où puis-je trouver les codes des erreurs Win32 ?

WINERROR.H, dans le répertoire INCLUDE de votre installation de système par défaut, contient les définitions des codes d’erreur correspondant aux fonctions API Win32.

Vous pouvez rechercher un code d’erreur en tapant ce code dans la fenêtre Espion ou dans la boîte de dialogue Espion express. Par exemple :

0x80000004,hr

Comment puis-je conserver le focus quand j’exécute mon application pas à pas ?

Exemple : Mon programme a un problème d’activation des fenêtres. Lorsque j'exécute mon programme en pas à pas avec le débogueur, je ne parviens pas à reproduire le problème, car le programme continue de perdre le focus. Existe-t-il un moyen d’éviter la perte de focus ?

Si vous disposez d'un autre ordinateur, utilisez le débogage distant. Vous pouvez faire fonctionner votre programme sur l'ordinateur distant pendant que vous exécutez le débogueur sur l'hôte. Pour plus d’informations, consultez Guide pratique pour sélectionner un ordinateur distant.

Comment puis-je déboguer des fonctions API Windows ?

Pour définir un point d’arrêt sur une fonction API Windows qui a chargé des symboles NT :

  • Dans le point d’arrêt de la fonction, entrez le nom de la fonction avec le nom de la DLL où réside la fonction (voir l’opérateur de contexte). Dans du code 32 bits, utilisez la forme décorée du nom de la fonction. Pour définir un point d’arrêt sur MessageBeep, par exemple, vous devez entrer ce qui suit.

    {,,USER32.DLL}_MessageBeep@4
    

    Pour obtenir le nom décoré, consultez Affichage des noms décorés.

    Vous pouvez tester le nom décoré et l’afficher dans le code désassemblage. Lors d’une pause au niveau de la fonction dans le débogueur Visual Studio, faites un clic droit sur la fonction dans l’éditeur de code ou la fenêtre de pile d’appels, puis choisissez Accéder au désassemblage.

  • Dans le code 64 bits, vous pouvez utiliser le nom non décoré.

    {,,USER32.DLL}MessageBeep
    

Étapes suivantes

Vous pouvez en découvrir plus sur le débogage de code natif dans Visual Studio en utilisant les liens suivants :