7
votes

Comment déboguer correctement et trouver des causes de crash?

Je ne sais plus quoi faire ... c'est sans espoir. Je suis fatigué de deviner ce qui cause les accidents. Récemment, j'ai remarqué que certains appels OpenGL collent des programmes au hasard sur certaines cartes GFX. Je suis donc vraiment paranoïaque que peut causer des accidents. La mauvaise chose sur cet accident est qu'elle ne se bloque qu'après une longue période d'utilisation du programme, je ne peux que deviner quel est le problème.

Je ne sais pas que je me souviens des changements que j'ai apportés au programme pouvant causer les crashs, son été si longtemps. Mais heureusement, la version précédente ne crash pas, alors je ne pouvais donc pas copier un code et perdre 10 heures pour voir à quel point il commence à s'écraser ... Je ne pense pas que je veux le faire pour le moment.

Le programme se bloque après que je sache à traiter les mêmes fichiers environ 5 fois de suite, chaque fois qu'il utilise environ 200 mégaoctets de mémoire dans le processus. Il se bloque à des moments aléatoires et après le processus de lecture.

J'ai créé une fonction de "sécurité" libre (), il vérifie le pointeur si ce n'est pas null, puis libère la mémoire, puis définit le pointeur sur NULL. N'est-ce pas comment cela devrait être fait?

J'ai regardé l'utilisation de la mémoire de la mémoire de la tâche et juste avant de l'avoir écrasé, il a commencé à manger 2 fois plus de mémoire que d'habitude. De plus, le chargement du programme est devenu exponentiellement plus lent chaque fois que j'ai chargé les fichiers; Les quelques premières charges ne semblaient pas beaucoup plus lentes les unes des autres, mais il a commencé à doubler rapidement les vitesses de charge. Que faut-il me parler de l'accident?

Aussi, dois-je libérer manuellement les vecteurs C ++ en utilisant clair ()? Ou sont-ils libérés après l'utilisation automatiquement, par exemple si j'allocie le vecteur dans une fonction, sera-t-il libéré chaque fois que la fonction est terminée? Je ne stocke pas les pointeurs dans le vecteur.

-

Bientôt: je veux apprendre à attraper les fichus bugs aussi vite que possible, comment puis-je faire ça? Utilisation de Visual Studio 2008.


4 commentaires

Avez-vous essayé d'utiliser un débogueur?


Nope, je ne sais pas comment ça marche. Lorsque le programme se bloque, il est écrit "Exception non confondue à 0x6944Adfd à Test.exe: 0xc0000005: Emplacement de lecture de violation d'accès 0x00000008". Ensuite, j'appuie "Break" et il est indiqué "Aucun symbole n'est chargé pour tout cadre de pile d'appels. Le code source ne peut pas être affiché." Ensuite, il offre une option pour montrer le démontage.


"Emplacement de la lecture d'une violation d'accès 0x00000008" Cela ressemble à vous avoir essayé de désirer un décalage avec un pointeur NULL (comme NullPtrtosomething-> STRUCTMember)


On dirait que vous devez activer le mode de débogage lorsque vous compilez.


7 Réponses :


3
votes

Un crash "aléatoire" qui se produit un jour après qu'une opération complexe est presque certainement le résultat de la corruption du tas. Les bogues de corruption en tas sont un chienne , puisqu'ils se manifestent généralement très loin de l'endroit qui a provoqué le bug. Ma suggestion, puisque vous êtes sous Windows, est d'utiliser Verificateur d'application , qui peut être téléchargé librement à partir de MS.

Lancez AV, configurez-le pour regarder votre programme et allumer toutes les options relatives à la mémoire. Puis exécutez votre programme sous un débogueur. (Ces deux choses vont faire fonctionner votre programme extrêmement lent.) Les contrôles supplémentaires que AV, espérons-le, espérons que votre programme s'écrase à un endroit différent de ce que vous ne voyiez jusqu'à présent, mais ce sera l'emplacement qui est la vraie cause du bogue.


1 commentaires

J'ai téléchargé ce programme de vérificateur, et je reçois ce message quand il se bloque "de première chance d'exception à 0x004046DB à Test.exe: 0xc0000005: Emplacement de lecture de violation d'accès 0x43461000". Comment savoir quelle ligne dans mon code qui est?



1
votes

Très probablement, vous obtenez une corruption de mémoire. Vous voudrez qu'un débogueur de mémoire de suivre cela; Vous pouvez trouver des recommandations ici .

J'ai créé une fonction gratuite (sécurisée "(), elle vérifie le pointeur si ce n'est pas null, puis libère la mémoire, puis définit le pointeur sur NULL.

Vérification de NULL n'est pas nécessaire car une standard conforme libre (quel VS2008 est) fera ce chèque pour vous. Il est toujours possible de libérer un pointeur indésirable qui peut causer des problèmes.

comme pour régler le pointeur sur NULL, cela peut aider mais ce n'est pas une panacée. Tout d'abord, vous ne pouvez pas définir le pointeur correct sur NULL. Par exemple, si vous faites cela: xxx

Tout ce que vous avez fait est défini le paramètre local de MyFree à NULL. La copie de l'appelant du pointeur est toujours laissée intacte.


2 commentaires

J'utilise: #define liber (point) si (point! = Null) {gratuit (point); point = null; } ne devrait-il pas fonctionner correctement?


@Newbie - tandis que cela ne causera pas de problèmes, que ce soit ce que vous espérez dépend de la structure du code. Disons que vous avez une fonction void proprep_foo (foo * f) {si (f) {Frees (f-> intérieure); libère (f); }} seulement le f local sur CleanUp_foo est défini sur NULL. Je trouve des choses comme votre librets utile pour les petits programmes avec une petite structure mais ne fonctionnent pas autant que vous obtenez une structure plus complexe.



1
votes

Comme dit plus tôt, c'est probablement une fuite de mémoire quelque part.

Visual Studio a des outils intégrés pour Ceci

Fondamentalement, vous prenez deux instantanés de la mémoire et comparez-les à un moment donné


0 commentaires

1
votes

première question, pourquoi utilisez-vous gratuitement () en C ++? Normalement, vous devez utiliser une nouvelle / Supprication pour la gestion de la mémoire ou une meilleure nouvelle combinaison avec des pointeurs intelligents.

Vous n'avez pas à effacer manuellement () les vecteurs. N'oubliez pas que si vous stockez des pointeurs à des objets dans le vecteur (ce qui n'est pas nécessairement bonne pratique, il y a de meilleurs conteneurs pour cela), vous devrez les détruire individuellement avant que le vecteur ne soit détruit. Comme vous l'avez dit, vous ne stockez pas les pointeurs dans le vecteur, le vecteur sera détruit lorsqu'il sera hors de portée - c'est-à-dire que l'objet contenant est détruit ou que le programme laisse la portée à l'intérieur d'une fonction.

Des accidents aléatoires sont généralement / souvent des bugs de mémoire, je vous recommanderais de vous tenir de votre véhicule avec un bon débogueur de mémoire. Sur des fenêtres qui signifie généralement purify ou limite de correction rationnelle. Bien sûr, il aide à déterminer ce qui a déclenché le crash en premier lieu - ne pas gérer une condition de mémoire hors mémoire? Null Pointer Dereefence? Rayons cosmiques?

Compte tenu de la réponse aux commentaires de votre question, voici ce que je ferais:

  • Changez l'interception d'exception VS2008 telle qu'elle va rompre sur une violation d'accès
  • Exécutez votre programme sous le débogueur, en mode de débogage - N'essayez pas de déboguer l'exécutable de la libération
  • Essayez de reproduire le comportement que vous voyez. Cela prendra plus de temps qu'en mode de sortie, mais vous devriez éventuellement y arriver. Vous aurez probablement aussi quelques faux positifs.
  • Si vous avez une bonne idée du pointeur (NULL) devient déréférencé, affirmer () le pointeur et exécutez le programme dans le débogueur à nouveau.

0 commentaires

0
votes

Faites attention à la pointe de Noah Roberts »et de JS Bangs '- Si vous n'êtes pas familier avec un débogueur, cela ressemble à il est temps que vous vous familiarisez.

Je suggérerais également un outil de valgrind - voir cette Alors question .

En outre, dois-je libérer manuellement les vecteurs C ++ en utilisant clair ()?

Non.


0 commentaires

0
votes

Vous devez vraiment apprendre à utiliser le débogueur. Appuyez sur le bouton Play en haut ou utilisez les fonctions de débogueur à distance si nécessaire. Si vous ne pouvez pas le suivre de cette façon, DRWTSN32 est également une option.


0 commentaires

1
votes

"Je ne me souviens pas des changements que j'ai faits au programme qui peut causer la Crashes, c'est si longtemps. Mais Heureusement, la version précédente n'a pas crash, donc je pouvais simplement copieriser code et déchets 10 heures à voir à quel point cela commence à se planter. "

C'est pourquoi Développement axé sur les tests (TDD) Rocks. Lisez-y dessus et voyez comment cela peut vous aider à éviter ces scénarios.


1 commentaires

Droite: Les tests de l'unité sont la documentation, à long terme.