35 votes

Résoudre des accidents aléatoires

Je reçois des plantages aléatoires sur mon application C++, il peut pas tomber en panne pendant un mois, et puis crash 10 fois en une heure, et parfois, il peut se bloquer sur le lancement, bien que parfois, il peut se bloquer après plusieurs heures de fonctionnement (ou ne plantera pas à tous).

J'utilise GCC sous GNU/Linux et MingW sous Windows, donc je ne peux pas utiliser le Visual Studio de Débogage JIT...

Je n'ai aucune idée sur la manière de procéder, à la recherche de façon aléatoire sur le code ne fonctionne pas, le code est ÉNORME (et une bonne partie n'était pas mon travail, aussi il a une bonne quantité de l'héritage des trucs sur elle), et j'ai aussi n'ont pas la moindre idée sur la façon de reproduire le crash.

EDIT: Beaucoup de personnes mentionné que... comment je fais un core dump, minidump ou whateverdump? C'est la première fois que j'ai besoin post-mortem de débogage.

EDIT2: en Fait, DrMingw capturé une pile d'appel, pas de mémoire d'infos... Malheureusement, la pile d'appel de ne pas m'a beaucoup aidé, parce que près de la fin, tout à coup, il aller dans une bibliothèque (ou quelque chose) que je n'ai pas les informations de débogage, résultant uniquement dans certains nombres hexadécimaux... Donc j'ai encore besoin de quelques décent dump que de donner plus d'informations (en particulier sur ce qui était dans la mémoire... en particulier, ce qui était dans l'endroit qui a donné le "erreur" violation d'accès)

Aussi, mon utilisation de l'application Lua et Luabind, peut-être que l'erreur est causée par un .script lua, mais je n'ai aucune idée sur la manière de debug qui.

29voto

Mitch Wheat Points 169614

Essayez de Valgrind (c'est gratuit, open-source):

Valgrind distribution comprend six de la production des outils de qualité: une erreur de mémoire, un détecteur de deux thread erreur de détecteurs, d'un cache et d' direction de la prévision du profileur, appelez-graphique de la génération du cache profiler, et un tas de profiler. Il comprend également deux outils expérimentaux: un tas/pile/réseau mondial de dépassement détecteur, et un SimPoint bloc de base vecteur générateur. Il s'exécute sur l' plates-formes suivantes: X86/Linux, AMD64/Linux, PPC32/Linux, PPC64/Linux, et X86/Darwin (Mac OS X).

Valgrind Questions Fréquemment Posées

Le Memcheck partie du paquet est probablement l'endroit pour commencer:

Memcheck est une erreur de mémoire détecteur. Il peut détecter les problèmes suivants qui sont courantes dans les programmes C et C++.

  • Accès à la mémoire, vous ne devriez pas, par exemple, le dépassement et underrunning tas blocs, qui écrase le haut de la pile, et l'accès à la mémoire après a été libéré.

  • À l'aide de valeurs non définies, c'est à dire des valeurs qui n'ont pas été initialisé, ou qui ont été calculées à partir d'autres une valeur non définie.

  • Incorrecte de libérer de la mémoire heap, tels que la double libération de tas de blocs, ou incompatibles utilisation de malloc/new/new[] ou gratuit/supprimer/delete[]

  • Chevauchement de la src et dst pointeurs dans memcpy et les fonctions associées.

  • Les fuites de mémoire.

15voto

user239558 Points 1548

Tout d'abord, vous avez de la chance que votre processus se bloque plusieurs fois dans un court délai. Cela devrait rendre facile à suivre.

C'est la façon de procéder.

  • Obtenir un vidage sur incident
  • Isoler un ensemble de potentiels suspects fonctions
  • Serrer en place un contrôle d'état
  • Répétez

Obtenir un vidage sur incident

Tout d'abord, vous avez vraiment besoin pour obtenir un fichier de vidage sur incident.

Si vous n'obtenez pas les vidages sur incident quand il se bloque, commencez par écrire un test qui produit fiable vidages sur incident.

Re-compiler le binaire avec des symboles de débogage ou assurez-vous que vous pouvez analyser les crash dump avec des symboles de débogage.

Trouver suspect fonctions

Étant donné que vous avez un fichier de vidage sur incident, de la regarder dans gdb ou votre favori débogueur et n'oubliez pas d'afficher tous les threads! Il pourrait ne pas être le fil que vous voyez dans gdb qui est bogué.

Regarder où gdb dit que votre binaire s'est écrasé, isoler un ensemble de fonctions que vous pensez peut provoquer le problème.

En regardant les différents blocages et isolement de sections de code qui sont souvent actifs dans tous les accidents est un vrai gain de temps.

Serrer en place un contrôle d'état

Une collision se produit généralement parce que certains état incohérent. La meilleure façon de procéder est souvent à resserrer les exigences de l'état. Vous faites cela de la façon suivante.

Pour chaque fonction, vous pensez peut provoquer le problème, le document juridique de l'état de l'entrée ou de l'objet doit avoir à l'entrée de la fonction. (Faire de même pour ce que l'etat de droit, il doit avoir à la sortie de la fonction, mais ce n'est pas trop important).

Si la fonction contient une boucle, document de l'état de droit, il doit, au début de chaque itération de boucle.

Ajouter affirme pour de telles expressions de l'etat de droit.

Répétez

Ensuite, répétez le processus. Si il se bloque toujours à l'extérieur de votre affirme, serrer l'affirme plus loin. À un certain point, le processus se crash sur une assertion et non pas à cause de certains crashs aléatoires. À ce stade, vous pouvez vous concentrer sur le fait d'essayer de comprendre ce que fait votre programme de passer d'un état de droit, de l'entrée à la fonction, pour un état illégales au point où l'assertion qui s'est passé.

Si vous avez une paire l'affirme avec la journalisation détaillée, il devrait être plus facile de suivre ce que fait le programme.

14voto

Nicholas Knight Points 9293

Si tout le reste échoue (en particulier si les performances sous le débogueur sont inacceptables), journalisation étendue. Commencez par les points d'entrée - l'application est-elle transactionnelle? Consignez chaque transaction à mesure qu'elle entre. Consignez tous les appels de constructeur pour vos objets de clé. Comme le crash est tellement intermittent, enregistrez les appels à toutes les fonctions qui pourraient ne pas être appelées tous les jours.

Vous aurez au moins commencer à réduire vers le bas où l'accident pourrait être.

8voto

sharptooth Points 93379

Démarrez le programme sous le débogueur (je suis sûr qu’il existe un débogueur avec GCC et MingW) et attendez qu’il se bloque sous le débogueur. Au moment du crash, vous pourrez voir quelle action spécifique échoue, consulter le code d'assemblage, les registres, l'état de la mémoire - cela vous aidera souvent à trouver la cause du problème.

8voto

ereOn Points 18624

Là où je travaille, les programmes en panne génèrent généralement un fichier core dump pouvant être chargé dans windbg.

Nous avons alors une image de la mémoire au moment où le programme s'est écrasé. Vous ne pouvez plus rien y faire, mais au moins cela vous donne la dernière pile d'appels. Une fois que vous connaissez la fonction qui s'est bloquée, vous pouvez alors identifier le problème et au moins réduire le problème à un scénario de test plus reproductible.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X