2010-07-26 2 views
1

Tout en conservant un ancien produit, je suis tombé sur une erreur qui entraîne le remplissage de l'écran avec des centaines de boîtes de message disant 'C++ Exception' et rien d'autre. Je traçais le problème à la ligne suivante:Pourquoi ProcessMessages peut-il lancer une exception C++?

Application->ProcessMessages(); 

Je comprends le but de cette ligne, pour traiter tous les messages dans la file d'attente de messages, mais je ne suis pas sûr de ce qui cause l'erreur.

Je ne suis pas à la recherche d'une solution spécifique, mais je me demande si quelqu'un d'autre a eu ce problème ou peut savoir quel genre de situations peut causer cela se produise.

La fermeture de toutes les boîtes de message entraîne l'application de revenir à la normale, le comportement attendu.

Mise à jour - Après quelques recherches supplémentaires, j'ai constaté que les erreurs ne sont pas nécessairement la faute de ProcessMessages. Les erreurs se produisent car le programme effectue des calculs intensifs et manque réellement de mémoire. Il semble que commenter ProcessMessages réduit la consommation de mémoire juste assez pour passer à travers les calculs sans erreurs. Par conséquent, ProcessMessages ressemble au coupable, mais en fait, ne l'est pas.

Il semble que je refactoring à faire.

Mise à jour 2 - Trois jours plus tard, je suis arrivé à la conclusion que l'erreur se produit uniquement lorsque ProcessMessages est appelé. Si je commente tous les appels à ProcessMessages (et à ma grande consternation, il y a beaucoup), l'application fonctionne très bien avec une consommation de mémoire constante, ce qui implique que les calculs intensifs ne sont pas aspirer la mémoire. La désactivation de l'appel provoque une nouvelle montée en flèche de la mémoire jusqu'au point d'erreur. Donc la question originale est la suivante: pourquoi ProcessMessages provoque-t-il cette erreur?

Il semblerait que certains appels sont faits à partir d'un événement de minuterie et d'autres sont fabriqués à partir de la principale exécution de l'application. Cela pourrait-il être un problème?

+0

Quelle bibliothèque utilisez-vous? –

+0

Je ne suis pas sûr de la bibliothèque utilisée. Il est construit avec Borland C++ Builder, si cela éclaire la question. ProcessMessages est une méthode de la classe TApplication pour les applications Windows C++ Builder. – Everett

+0

Essayez d'attraper 'std :: runtime_error' - si l'exception est basée sur cette classe, vous pouvez obtenir plus d'informations' e.what() '. – AndiDog

Répondre

0

Cela est principalement une supposition, mais de ce que je vois, c'est un problème causé par un grand journal arrière de messages. Pendant le gros calcul, l'application ne répond plus pendant un nombre de secondes alors qu'un grand nombre de messages sont lancés dans la file d'attente (nombre d'entre eux sont des événements de minuterie). Lorsque le calcul est terminé et que ProcessMessages est appelé, l'application est submergée par trop de messages et leur envoi entraîne un débordement de mémoire.Si j'ajoute ProcessMessages après chaque itération du calcul pour distribuer les événements tels qu'ils viennent, la consommation de mémoire reste constante.

Son plausible?

2

Cela ressemble certainement à une erreur d'application dans le code de traitement des messages de la bibliothèque avec un gestionnaire d'exception catch-all qui affiche un message générique en utilisant l'API Win32 :: MessageBox() en réponse. Recherchez la chaîne "C++ Exception" dans le code et voyez si elle se trouve dans un catch(...), catch (std::exception&) ou un gestionnaire similaire. Il est possible qu'ils utilisent le Win32 unhandled exception filter à la place.

De préférence, vous devez exécuter le programme sous le débogueur Visual Studio avec le jeu de dialogue Debug-> Exceptions pour intercepter les exceptions C++ lorsqu'elles sont levées plutôt que si elles sont non gérées. De cette façon, vous trouverez le (s) site (s) générant l'exception immédiatement. Si vous ne pouvez pas exécuter sous le débogueur, vous devrez peut-être personnaliser le gestionnaire d'exceptions non gérées avec les macros __LINE__ et __FILE__ C afin que vous puissiez au moins savoir quelle méthode génère l'erreur. Passer de l'affichage d'une boîte de message à l'API OutputDebugString() de Win32 et utiliser un outil comme DebugView pour regarder les chaînes de débogage.

Questions connexes