Почему ProcessMessages может генерировать исключение C ++? - PullRequest
1 голос
/ 26 июля 2010

При обслуживании старого продукта я столкнулся с ошибкой, которая приводит к тому, что на экране появляются сотни окон с сообщениями «C ++ Exception» и ничего больше.Я проследил проблему до следующей строки:

Application->ProcessMessages();

Я понимаю цель этой строки, чтобы обработать все сообщения в очереди сообщений, но я не уверен, что является причиной ошибки.

Я не ищу конкретного решения, но мне интересно, если кто-то еще имел эту проблему или может знать, какие ситуации могут вызвать это.

Закрытие всех окон сообщений вызываетприложение, чтобы вернуться к нормальному, ожидаемому поведению.

Обновление - После дополнительного поиска я обнаружил, что ошибки не обязательно являются ошибкой ProcessMessages.Ошибки возникают из-за того, что программа выполняет интенсивные вычисления и фактически не хватает памяти.Кажется, что комментирование ProcessMessages сокращает потребление памяти настолько, чтобы пройти вычисления без ошибок.Следовательно, ProcessMessages выглядит как виновник, но на самом деле это не так.

Похоже, у меня есть какой-то рефакторинг.

Обновление 2 - Три дня спустя,Я пришел к выводу, что ошибка происходит только при вызове ProcessMessages.Если я прокомментирую все вызовы ProcessMessages (и, к моему ужасу, их много), то приложение будет работать нормально с постоянным потреблением памяти, подразумевая, что интенсивные вычисления не высасывают память.Раскомментирование вызова снова приводит к стремительному увеличению памяти.Таким образом, возникает первоначальный вопрос: почему ProcessMessages вызывает эту ошибку?

Может показаться, что некоторые вызовы выполняются из события таймера, а другие - из основного приложения.Может ли это быть проблемой?

Ответы [ 2 ]

2 голосов
/ 26 июля 2010

Это, безусловно, звучит как ошибка приложения в коде обработки сообщений библиотеки с обработчиком исключений для всех ловушек, который показывает обобщенное сообщение с использованием Win32 :: MessageBox () API в ответ.Найдите строку «C ++ Exception» в коде и посмотрите, есть ли она в обработчике catch(...), catch (std::exception&) или аналогичном.Возможно, вместо этого они используют фильтр необработанных исключений Win32 .

Предпочтительно, чтобы программа запускалась в отладчике Visual Studio с установленным диалоговым окном Debug-> Exceptions, чтобы перехватывать исключения C ++, когдаони брошены, а не если они не обрабатываются.Таким образом, вы сразу найдете сайты, которые генерируют исключение.

Если вы не можете запустить под отладчиком, возможно, вам придется настроить обработчик необработанного исключения с помощью __LINE__ и __FILE__Макросы C, так что вы можете хотя бы узнать, какой метод генерирует ошибку.Переключитесь с отображения окна сообщения на Win32 OutputDebugString () API и используйте инструмент, подобный DebugView , для просмотра строк отладки.

0 голосов
/ 30 июля 2010

Это в основном предположение, но из того, что я вижу, это проблема, вызванная большим обратным журналом сообщений.Во время больших вычислений приложение перестает отвечать на запросы в течение нескольких секунд, в то время как большое количество сообщений выбрасывается в очередь (многие из них являются событиями таймера).Когда вычисления завершаются и вызываются ProcessMessages, приложение перегружается слишком большим количеством сообщений, и их отправка приводит к переполнению памяти.Если я добавлю ProcessMessages после каждых нескольких итераций вычислений для отправки событий по мере их поступления, потребление памяти останется постоянным.

...