3 votes

Comment attraper une exception non gérée d'une application .Net avec procdump (ou similaire) ?

La longue histoire (ennuyeuse)

Actuellement, j'ai une application qui génère une exception sur un seul PC. Après quelques recherches, j'ai pu encapsuler le problème avec un petit exemple d'application, mais la vraie raison reste cachée.

En raison du fait que sur ce PC, Visual Studio n'est pas installé et que nous ne sommes pas en mesure de le faire, j'ai cherché une autre solution pour trouver la véritable raison.

Dans une première approche, j'ai dépouillé de plus en plus ma petite application en lisant attentivement le message d'exception, en le comparant au code et en essayant l'erreur pour arriver à la ligne concrète du problème. Mais cela ne m'a pas aidé à obtenir toutes les informations sur les valeurs actuelles de toutes les variables utilisées, etc.

J'ai donc cherché un autre meilleur pour obtenir les informations dont j'ai besoin. J'ai déjà lu sur Dumps y Minidumps depuis longtemps, mais je n'en ai jamais eu besoin, car jusqu'à présent j'ai toujours pu reproduire le scénario décrit par l'utilisateur sur ma machine de développement ou de test.

Mais cette fois-ci, il semble qu'il n'y ait qu'un seul PC qui ait le problème et, malheureusement, il n'est pas possible de changer toute la machine ou d'installer tout ce qu'il y a de neuf.

Pour me familiariser avec l'utilisation des dumps, j'ai écrit une simple application de test en c#, contenant un seul bouton qui ne fait rien d'autre que throw new ArgumentException("Test");

Je dois maintenant créer un fichier dump magique après avoir appuyé sur le bouton malveillant, le lire dans Visual Studio 2008 Professional et l'examiner comme une application normale dans VS, à l'exception de ce qui suit Étape suivante etc. ne fonctionnera pas.

Pour autant que je sache, le meilleur outil pour créer un dumping à un moment précis est le suivant procdump En effet, il est possible de définir le moment où un ou plusieurs dumps sont effectués.

Je l'ai donc simplement téléchargé et je l'ai démarré en appelant procdump -o -e MyApp.exe d:\MyApp.dmp . Elle affirme que MyApp.exe n'existe pas. D'accord, c'est ma faute. Il suffit de démarrer MyApp d'abord et ensuite procdump.

Procdump s'exécute maintenant en me montrant toutes les options qu'il utilise et semble attendre une exception non gérée. Rien de plus facile, j'appuie simplement sur mon bouton malveillant ... et rien ne se passe dans procdump.

Au lieu de cela, une fenêtre de dialogue de mon application apparaît, expliquant qu'une exception non gérée s'est produite (surprise, surprise) et ce que je souhaite faire (Détails, Continuer, Quitter). Mais peu importe ce que je sélectionne, procdump n'est pas capable de créer un fichier dump automatiquement.

Si j'y vais et que j'appelle procdump -o MyApp.exe d:\MyApp.dmp lorsque la boîte de dialogue est affichée, le fichier dump semble être inutile, car après l'avoir ouvert dans VS, la pile d'appel est juste suspendue quelque part dans ntdll.dll mais nulle part dans mon code (je suppose qu'il s'agit de la MessageQueueue du dialogue qui attend des clics de souris).

Si je regarde de plus près les détails, vous trouverez des informations sur la façon de déléguer l'exception non gérée à un débogueur JIT. Mais je ne veux pas d'un débogueur JIT, je voudrais planter l'application pour obtenir le fichier dump.

Après ces essais, j'ai trouvé ClrDump mais cela n'a pas produit de meilleurs dumps (si je le charge dans VS et que je regarde la pile d'appels).

En tenant compte de ces informations, vous êtes maintenant (espérons-le) en mesure de me fournir une solution (fonctionnelle) pour mon application .Net :

La (courte) question

Comment puis-je créer un fichier dump lorsqu'une exception non gérée se produit dans une application .net, que je puisse charger les fichiers .pdb de MyApp et voir dans quelles circonstances l'exception a été levée ?

La réponse

Avec l'aide de Naveen et Lex Li, j'ai pu comprendre un peu mieux comment fonctionne le débogage avec les crash dumps. Et maintenant, j'aimerais juste récapituler tout ce qui est nécessaire pour que cela fonctionne :

Lorsque vous souhaitez obtenir un aperçu d'un processus, vous avez le choix entre plusieurs outils pour réaliser ce travail :

  • Procdump
    • un outil de ligne de commande facile à utiliser qui peut créer des dumps dans des scénarios compliqués, mais il n'a pas la capacité de créer des dumps. pas pour attraper les exceptions non gérées de .net.
  • DebugDiag
    • outil graphique simple qui peut créer des dumps lors de crashs (même les exceptions .net), mais il ne peut pas créer de dumps lors de scénarios avancés comme Procdump.

Comme vous pouvez le constater, vous disposez de deux outils capables de créer des dumps dans des circonstances différentes, de sorte que les deux sont plus partenaires que rivaux pour créer un dump au moment voulu.

Après avoir créé un dump avec l'un des outils ci-dessus, il est temps d'analyser le dump pour trouver la raison du problème. Pour l'analyse, vous pouvez utiliser WinDbg. Il fait partie du programme Outils de débogage pour Windows et peut être obtenu auprès de Microsoft. Malheureusement, la barrière d'entrée de WinDbg est assez élevée, mais il est vraiment puissant. Jetez peut-être un coup d'œil à ce blog pour mieux comprendre comment utiliser cet outil.

Si vous avez une application .Net 4 et que vous utilisez Visual Studio 2010, vous pouvez également l'utiliser pour l'analyse. Il est beaucoup plus facile à utiliser, grâce à une meilleure interface graphique, mais il n'a pas la puissance de WinDbg. Pour obtenir une meilleure comparaison, vous devriez jeter un coup d'œil à cet article .

Enfin, vous pouvez également utiliser la dll sos.dll dans Visual Studio 2008. Voici l'article en décrivant ce que vous pouvez faire avec.

3voto

Naveen Points 2653

DebugDiag est l'un des moyens les plus simples d'obtenir une vidange de la mémoire sur la base d'une exception.

Consultez la section d'aide "Configure Exception Dialog" dans debugdiag pour générer un dump basé sur l'exception.

Voici un exemple de génération d'un vidage complet de la mémoire à partir d'une exception de type ArgumentException

enter image description here

1voto

Lex Li Points 18214

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