Исключения и нарушения прав доступа в событиях Paint в Windows

После выполнения какого-то нового кода мое приложение на C++ начало вести себя странно (неправильные или неполные обновления экрана, иногда вообще не обновлялись). Через некоторое время мы узнали, что новый код вызывает нарушение прав доступа. Как ни странно, приложение просто продолжает работать (но с некорректными обновлениями экрана).

Сначала мы подумали, что проблема вызвана конструкцией «try-catch(...)» (вставленной сверхактивным бывшим коллегой), но спустя несколько часов (тщательно просматривая стек вызовов, добавляя множество точек останова,... ) мы обнаружили, что если в событии рисования происходит нарушение прав доступа, Windows его перехватывает и просто продолжает выполнять приложение.

  • Это нормальное поведение?
  • Нормально ли, что Windows перехватывает исключения/ошибки во время события рисования?
  • Есть ли способ отключить это? (если нет, это будет означать, что мы должны всегда запускать в отладчике все включенные исключения при тестировании нашего кода).

РЕДАКТИРОВАТЬ:

  • В XP происходит правильный сбой (желаемое поведение после нарушения прав доступа)
  • В Vista и Windows 7 приложение продолжает работать

person Patrick    schedule 25.05.2010    source источник
comment
возможный дубликат нарушения прав доступа в WM_PAINT не обнаружен   -  person Patrick    schedule 25.05.2010


Ответы (2)


Это известный дефект. Проверьте исправление. http://support.microsoft.com/kb/976038

person mljack    schedule 05.08.2010
comment
Действительно, похоже, что это так. Мы будем исследовать это дальше и посмотрим, как мы можем правильно решить эту проблему. Спасибо за совет. - person Patrick; 06.08.2010

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

[Я удалил остальную часть предыдущего ответа, потому что, основываясь на комментариях Патрика и небольшом исследовании, он был явно неприменим к рассматриваемой проблеме. ]

Следуя комментарию Патрика, я провел быстрый тест и продублировал поведение под Windows 7. Я начал с действительно минимальной программы (базовой программы, сгенерированной VS 2008 для проекта Win32) и все, что я добавил, было записью на несуществующий адрес. Конечно же, вы не получите никаких признаков того, что произошло что-то плохое.

Просто для улыбки я сделал быстрый тест, чтобы увидеть, как именно он реагирует на исключение. Что бы это ни стоило, он не возобновляется после исключения, он просто перехватывает его и пропускает оставшуюся часть кода в обработчике WM_PAINT.

Я немного поискал в MSDN, но до сих пор не нашел никакой документации, объясняющей, как и почему это произошло, можно ли это отключить, и если да, то как, или многое другое. Однако я должен согласиться: это действительно серьезная проблема - если я вызвал нарушение прав доступа (нет, этого не могло случиться!), я хочу, чтобы программа аварийно завершилась как можно быстрее и основательнее. Маскировка ошибки (особенно такой серьезной, как нарушение прав доступа) — крайне плохая идея!

person Jerry Coffin    schedule 25.05.2010
comment
Проблема не в неправильном обновлении, а в том, что приложение продолжает работать после нарушения прав доступа в сообщении WM_PAINT (по крайней мере, в Vista). - person Patrick; 25.05.2010
comment
Нет, программа не останавливается! Мы попробовали точно такой же код, как в вашем комментарии (за исключением использования 123 вместо 1 :-)): в XP он вылетает, в Vista он не вылетает. - person Patrick; 25.05.2010
comment
Джерри, рад, что мы согласны с этим, +1. Тем временем я нашел идентичный вопрос (stackoverflow.com/questions/1487950/). К сожалению, хорошего ответа пока нет. В настоящее время я изучаю использование VectoredExceptionHandling для решения этой проблемы. - person Patrick; 25.05.2010