Why might ProcessMessages throw a C++ Exception?
While maintaining an old product, I came across an error that results in the screen being filled up with hundreds of message boxes saying 'C++ Exception' and nothing else. I traced the problem to the following line:
Application->ProcessMessages();
I understand the purpose of this line, to process all the messages in the message queue, but I'm not sure what's causing the error.
I'm not looking for a specific solution, but I'm wondering if anyone else has had this problem or might know what sor开发者_运维知识库t of situations may cause this to happen.
Closing all the message boxes causes the application to return to normal, expected behavior.
Update - After some more searching, I found that the errors are not necessarily the fault of ProcessMessages. The errors occur because the program is doing some intensive calculations and actually runs out of memory. It seems like commenting out ProcessMessages reduces the memory consumption just enough to get through the calculations without errors. Hence, ProcessMessages looks like the culprit, but in fact, is not.
It looks like I have some refactoring to do.
Update 2 - Three days later, I have come to the conclusion that error only happens when ProcessMessages is called. If I comment all the calls to ProcessMessages (and to my dismay, there are many), then the application runs fine with a constant memory consumption, implying that the intensive calculations are not sucking up the memory. Uncommenting a call causes the memory to skyrocket to the point of error again. So the original question stands: why does ProcessMessages cause this error?
It would appear that some calls are made from a timer event and others are made from the main application execution. Might this be a problem?
It certainly sounds like an application error in the library's message-processing code with a catch-all exception handler that shows a generic message using the Win32 ::MessageBox() API in response. Look for the string "C++ Exception" in the code and see if it is in a catch(...)
, catch (std::exception&)
or similar handler. It's possible that they are using the Win32 unhandled exception filter instead.
Preferably, you should run the program under the Visual Studio debugger with the Debug->Exceptions dialog set to catch C++ exceptions when they're thrown rather than if they are unhandled. That way you'll find the site(s) generating the exception immediately.
If you can't run under the debugger, You may have to customize the unhandled exception handler with the __LINE__
and __FILE__
C macros so you can at least find out what method is generating the error. Switch from displaying a message box to Win32's OutputDebugString() API and use a tool like DebugView to watch the debugging strings.
This is mostly a guess, but from what I see, it's a problem caused by a large back log of messages. During the large computation, the application becomes unresponsive for number of seconds while a large number of messages are thrown on the queue (many of these are timer events). When the computation finishes and ProcessMessages is called, the application is overwhelmed with too many messages and dispatching them all causes a memory overflow. If I add ProcessMessages after every few iterations of the computation to dispatch events as they come, the memory consumption remains constant.
Sound plausible?
精彩评论