Quelle est la cause de “Cette application a demandé au Runtime de le terminer de manière inhabituelle”?

Il y a une erreur commune qui est lancée par le Visual C Runtime:

Cette application a demandé au Runtime de le terminer de manière inhabituelle.
Veuillez contacter l’équipe d’assistance de l’application pour plus d’informations.

Que signifie réellement ce message d’erreur?


Permettez-moi d’utiliser une parabole pour expliquer exactement ce que je demande.

Si je vois un message:

Exception: violation d’access (0xc0000005), adresse 0x702be865

Cette violation d’access n’a rien à voir avec le harcèlement sexuel, ou avec une personne qui tente de pénétrer dans mon ordinateur (pas plus que General Failure n’était un général de brigade qui essayait de lire mon lecteur C, ou d’être traîné en prison pour opération illégale dans Windows 95).

Dans ce cas, la violation d’access correspond à la constante EXCEPTION_ACCESS_VIOLATION (déclarée dans winbase.h avec la valeur 0xC0000005). Cette constante un code d’erreur d’exception possible qui peut être retourné dans une structure EXCEPTION_RECORD . Le code ACCESS_VIOLATION signifie que le programme a essayé de lire ou d’écrire dans une adresse en mémoire qu’il ne devrait pas être. Si vous essayez de lire à partir d’une adresse mémoire qui n’a jamais été allouée, vous faites quelque chose d’horriblement mauvais – et l’exception vous le dit.

Cela se produit généralement lorsqu’un programme a un pointeur sur la mémoire qui n’est pas ou n’est plus valide. La solution est d’arrêter d’essayer d’accéder à la mémoire qui n’est pas valide.

Note : je ne demande pas :

  • pourquoi le programme x reçoit-il une erreur C0000005?
  • pourquoi mon code reçoit-il une violation d’access?
  • Comment puis-je déboguer une violation d’access?

Donc, si je vous ai demandé ce qui cause une violation d’access , vous ne me diriez pas de vérifier la trace de la stack, de regarder la fenêtre de sortie ou de poster un code exemple. Vous diriez: “C’est d’essayer d’accéder à la mémoire qui n’est pas valide.”


Retour à ma question Que signifie l’erreur suivante:

Cette application a demandé à Runtime de se terminer de manière inhabituelle.

Je suis (assez) certain que la bibliothèque Microsoft Visual C Runtime n’a pas de fonction:

 void TerminateRuntime(bool UnusualWay); 

Je dois donc essayer de comprendre ce que cela signifie réellement:

  • Que signifie mettre fin à la bibliothèque d’exécution C visuelle? (msvcrt est une DLL, vous ne la terminez pas, vous ne l’utilisez plus)
  • Quelle serait une manière habituelle de mettre fin à MSVCRT?
  • Quelqu’un choisirait-il de le terminer d’une manière inhabituelle ?
  • La manière inhabituelle d’aujourd’hui est-elle en réalité une forme longtemps obsolète de ce qui était la manière habituelle ?
  • Si je le terminais (à tort) de manière inhabituelle, que ferais-je pour le terminer de la manière habituelle ?

En d’autres termes: quelle erreur le MSVCRT détecte-t-il et se cache-t-il derrière le message d’erreur non informatif?

Vous obtenez ce message lorsque la fonction abort() est appelée.

De MSDN:

avorter

Abandonne le processus en cours et renvoie un code d’erreur.

 void abort( void ); 

Valeur de retour

abort ne renvoie pas le contrôle au processus appelant. Par défaut, il termine le processus en cours et renvoie un code de sortie de 3.

Remarques

Par défaut, la routine d’ abandon imprime le message:

“Cette application a demandé au Runtime de le terminer de manière inhabituelle. Veuillez contacter l’équipe d’assistance de l’application pour plus d’informations.”

Il semble que dans la version récente du runtime VC, le message a été remplacé par “abort () a été appelé” peut-être pour clarifier ce que cela signifie réellement. Si vous souhaitez reproduire ce message, utilisez un ancien moteur d’exécution VC (VC ++ 6.0 à coup sûr) et appelez abort() .

En interne, lorsque abort() est appelé, il appelle une fonction _amsg_exit , définie dans internal.h, qui “émet essentiellement le message d’erreur d’exécution vers stderr pour les applications de console ou affiche le message dans une boîte aux lettres pour les applications Windows”. Le message d’erreur pour “Cette application a demandé au Runtime de le terminer de manière inhabituelle” est défini dans le fichier cmsgs.h:

cmsgs.h :

 #define _RT_ABORT_TXT "" EOL "This application has requested the Runtime to terminate it in an unusual way.\nPlease contact the application's support team for more information." EOL 

et le code d’erreur transmis ( _RT_ABORT ) est défini dans rterr.h:

rterr.h

 #define _RT_ABORT 10 /* Abnormal program termination */ 

Donc, alternativement, vous pouvez reproduire cela en appelant _amsg_exit( _RT_ABORT )


Mise à jour par question : Deux semaines après avoir posé cette question, Raymond Chen a répondu sur son propre blog :

Vous exécutez votre programme, puis il quitte soudainement le message. Cette application a demandé au Runtime de le terminer de manière inhabituelle. Qu’est-il arrivé?

Ce message est imprimé par la fonction runtime C abandonnée , la même fonction qui provoque également la fin de votre programme avec le code de sortie 3 .

Votre programme pourrait appeler abort explicitement, ou il pourrait être appelé implicitement par la bibliothèque d’exécution elle-même.

  • Les appels de macro assert s’interrompent lorsqu’une assertion échoue.
  • Par défaut, la fonction terminate appelle des interruptions.

Le standard C ++ définit les conditions dans lesquelles le terminate est appelé, et sa liste est longue, je ne vais donc pas me répéter ici. Consultez votre copie préférée de la norme C ++ pour plus de détails. (La raison la plus courante est de lancer une exception non gérée.)