Структурированный обработчик исключений (SEH) не обнаруживает повреждение кучи

Я пишу небольшую утилиту (VC 2010, без clr), которая выполняет одну простую задачу (растеризация) с использованием сторонней библиотеки. Позже утилита будет использоваться более крупным приложением. Иногда утилита дает сбой из-за повреждения кучи в сторонней библиотеке. Это нормально, но Windows (Vista / 2008) показывает хорошо известный диалог «Программа перестала работать ... Закрыть / Отладить программу». что не подходит в моем случае (на стороне сервера). Утилита должна аварийно завершить работу / прекратить работу без каких-либо видимых эффектов.

Для этого я установил SEH для необработанного исключения (SetUnhandledExceptionFilter). Обработчик отлично вызывается для таких исключений, как AV (* (PDWORD) 0 = 0), но по какой-то причине он не запускается в случае повреждения кучи. Повреждение происходит в dllmain одной из сторонних библиотек dll, пока она выгружается.

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


person AC.    schedule 07.12.2011    source источник
comment
DllMain () особенный. Windows не может допустить сбоя без серьезной дестабилизации процесса. Он перехватывает исключения SEH во время работы, поэтому ваш фильтр не будет работать. Вы ничего не можете с этим поделать, исправьте ошибку. Отключите WER на сервере, задавайте вопросы на serverfault.com   -  person Hans Passant    schedule 07.12.2011
comment
Спасибо, Ганс. Это имеет смысл. Попробую решить свою первоначальную проблему другим способом.   -  person AC.    schedule 07.12.2011
comment
Кроме того, в некоторых ситуациях это может быть проблемой: stackoverflow.com/questions/19656946/   -  person Maxim Kogan    schedule 17.09.2014


Ответы (2)


По-видимому, это намеренно, что повреждения кучи не могут быть обнаружены пользовательскими обработчиками исключений, даже если они генерируются как исключения с их собственным кодом исключения (0xC0000374 «STATUS_HEAP_CORRUPTION»). Вот отчет об ошибке Visual C ++, который был закрыт как «не исправлю»:

https://connect.microsoft.com/VisualStudio/feedback/details/664497/cant-catch-0xc0000374-exception-status-heap-corruption

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

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

Что касается предотвращения диалога, в реестре вы можете либо полностью отключить WER, либо просто отключить диалог, чтобы процесс не блокировался:

https://msdn.microsoft.com/de-de/library/windows/desktop/aa366711(v=vs.85).aspx (см. «DontShowUI»)

person mooware    schedule 04.04.2017

но по какой-то причине он не запускается в случае повреждения кучи. Повреждение происходит в dllmain одной из сторонних библиотек dll, пока она выгружается.

Повреждение кучи - это неопределенное поведение. Он может генерировать исключения, может и иначе. Если сторонняя библиотека с ошибками испортила вашу кучу, тогда возникает вопрос: «Почему вы вообще позволяете им возиться с вашей кучей?»

Диалог «программа перестала работать» отображается всякий раз, когда процесс завершается ненормально. Не все аварийные завершения процесса являются результатом исключений. Многие ошибки (например, переполнение стека, неправильное выравнивание стека и т. Д.) Вызывают мгновенное завершение процесса, которое может отображать это сообщение, но не дает вам возможности обработать ошибку.

(Также см. Замечательный комментарий Ганса выше)

person Billy ONeal    schedule 07.12.2011