1

Je reçois rarement un rapport de quelque utilisateur que l'application elle-même a pris fin avec une boîte de message suivant:Qu'est-ce que "Microsoft Visual C++ Visual Runtime Library: Erreur d'exécution!" et comment puis-je le capturer?

 
Microsoft C++ Visual Runtime Library 

Runtime error! 

Program: XXXXX.exe 

This application has requested the Runtime to terminate it in an unusual way. 
Please contact the application's support team for more information. 

Malheureusement, l'application se termine silenly après avoir affiché le message. Nous avons une génération de vidage sur crash sur les exceptions structurées, mais comme il n'y a aucune exception ici, aucun vidage sur incident n'est généré.

Qu'est-ce qui peut causer ce message?

Existe-t-il un moyen de changer l'application afin qu'au lieu de (ou en plus de) montrer le message, une minidump est générée (ou une autre gestion personnalisée est effectuée par l'application)?

+0

Vous aurez besoin d'un minidump pour le déboguer. Demandez à votre utilisateur d'en créer un pendant que la boîte de dialogue est affichée. Gestionnaire des tâches dans Vista/Win7 peut le faire. –

+0

Je préférerais l'application pour générer une minidump automatiquement, tout comme quand elle se bloque. – Suma

Répondre

4

Le message est produit par abort(), qui peut être appelé directement ou par des exceptions mal conçues - voir unexpected() ou terminate(), comme décrit dans Disable Microsoft Visual C++ Runtime Error. Si le message est affiché ou non peut être ajusté en utilisant _set_abort_behavior appel. Sur XP et plus tard, l'application devrait créer une minidump par défaut et l'envoyer au service Windows Error Reporting. Si vous avez besoin d'un gestionnaire personnalisé (par exemple, un vidage sur incident personnalisé), la seule possibilité (non standard) semble être de fournir votre propre implémentation pour la fonction abort().

L'implémentation par défaut de abort dans Microsoft C Runtime Library ne suit:

  • montre la boîte de message ou imprime le message à la console
  • soulève gestionnaire pour SIGABRT en cas de
  • si faute rapports est permis, alors
    • supprime tout gestionnaire d'exceptions non gérées à l'aide SetUnhandledExceptionFilter (NULL)
    • exécute UnhandledExceptionFilter avec une information d'exception artificiellement préparée
  • appels _exit (3) pour terminer le processus sans nettoyage

supplémentaires, y compris un code suivant dans votre source rend l'application pour effectuer la gestion des exceptions structurées par défaut (y compris tout filtre que vous avez peut-être installé):

extern "C" void __cdecl abort (void) 
{ 
    volatile int a = 0; 
    a = 1/a; 
} 
+0

Ceci résume ce que j'ai appris jusqu'à présent - merci à sharptooth pour ses liens et ses conseils. – Suma

+1

Remplacez-vous efficacement l'implémentation CRT de 'abort()' par la vôtre? – sharptooth

+0

Oui, exactement. Attention: ce n'est pas standard (comme défini par la norme, si vous utilisez des en-têtes système, vous ne pouvez pas fournir vos propres implémentations de fonctions définies dans ces en-têtes), alors assurez-vous de bien comprendre ce que vous faites. – Suma

3

L'application a appelé abort() probablement parce que terminate() a été appelée après qu'une exception a échappé à un destructeur lors du déroulement de la pile ou parce qu'une exception n'a pas été appelée. Pour plus de détails, voir an answer à this related question. Fondamentalement, vous devez attraper et gérer toutes les exceptions au niveau supérieur, ne laissez pas les exceptions échapper aux destructeurs. Démarrez votre programme sous le débogueur et activez "Arrêter quand l'exception est levée" pour trouver ce qui ne va pas et réparer.

+0

L'exception C++ n'est pas activée dans l'application. Je comprends qu'il pourrait être abort() appelé d'un autre endroit. Y a-t-il une autre raison?Existe-t-il un moyen de contourner le traitement, de faire quelque chose d'autre au lieu de montrer le message? – Suma

+0

@Suma: Vous pouvez utiliser '_set_abort_behavior()' pour supprimer l'affichage de la boîte de message. Vous pouvez également utiliser 'set_terminate()' pour remplacer le gestionnaire 'terminate()'. Et comment les exceptions C++ ne peuvent-elles pas être activées? – sharptooth

+0

Aussi "Démarrer votre programme sous débogueur" n'est pas utile dans mon cas, car cela ne m'est jamais arrivé. Il arrive très rarement, je reçois ce rapport peut-être quelques fois par an d'un utilisateur. – Suma