174 votes

Comment déboguer les erreurs de corruption de tas ?

Je débogue une application C++ multithread (native) sous Visual Studio 2008. En des occasions apparemment aléatoires, j'obtiens une erreur "Windows a déclenché un point d'arrêt..." avec une note indiquant que cela pourrait être dû à une corruption du tas. Ces erreurs ne font pas toujours planter l'application immédiatement, mais il est probable qu'elle se plante peu après.

Le gros problème de ces erreurs est qu'elles n'apparaissent qu'après que la corruption a eu lieu, ce qui les rend très difficiles à repérer et à déboguer, surtout dans une application multithread.

  • Quelles sortes de choses peuvent provoquer ces erreurs ?

  • Comment puis-je les déboguer ?

Les conseils, outils, méthodes, éclairages... sont les bienvenus.

1voto

John Saunders Points 118808

En plus de chercher des outils, pensez à chercher un coupable probable. Utilisez-vous un composant, que vous n'avez peut-être pas écrit vous-même, qui n'a peut-être pas été conçu et testé pour fonctionner dans un environnement multithread ? Ou simplement un composant que vous n'avez pas connaître a fonctionné dans un tel environnement.

La dernière fois que cela m'est arrivé, il s'agissait d'un paquet natif qui était utilisé avec succès depuis des années à partir de travaux par lots. Mais c'était la première fois dans cette entreprise qu'il était utilisé à partir d'un service Web .NET (qui est multithread). C'était tout : ils avaient menti sur le fait que le code était thread safe.

1voto

KindDragon Points 1656

Vous pouvez utiliser les macros Heap-Check de VC CRT pour _CrtSetDbgFlag : _CRTDBG_CHECK_ALWAYS_DF ou _CRTDBG_CHECK_EVERY_16_DF .. _CRTDBG_CHECK_EVERY_1024_DF .

0voto

dario_ramos Points 2919

J'aimerais ajouter mon expérience. Ces derniers jours, j'ai résolu un cas de cette erreur dans mon application. Dans mon cas particulier, les erreurs dans le code étaient les suivantes :

  • Suppression d'éléments d'une collection STL pendant l'itération sur celle-ci (je crois qu'il existe des drapeaux de débogage dans Visual Studio pour détecter ces choses ; je l'ai remarqué pendant la révision du code).
  • Celle-ci est plus complexe, je vais la diviser en plusieurs étapes :
    • À partir d'un thread C++ natif, rappel dans le code géré
    • Dans les terres gérées, appelez Control.Invoke et dispose d'un objet géré qui englobe l'objet natif auquel le callback appartient.
    • Puisque l'objet est toujours vivant dans le thread natif (il restera bloqué dans l'appel de la fonction de rappel jusqu'à ce que l'appel de la fonction de rappel soit terminé), l'objet ne sera pas bloqué. Control.Invoke extrémités). Je dois préciser que j'utilise boost::thread J'utilise donc une fonction membre comme fonction de fil.
    • Solution : Utiliser Control.BeginInvoke (mon interface graphique est faite avec Winforms) pour que le thread natif puisse se terminer avant que l'objet soit détruit (le but du callback est précisément de notifier que le thread s'est terminé et que l'objet peut être détruit).

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