Структурный обработчик исключений (SEH) не улавливает повреждение кучи - PullRequest
1 голос
/ 07 декабря 2011

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

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

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

Ответы [ 2 ]

1 голос
/ 04 апреля 2017

Очевидно, что намеренно, что повреждения кучи не могут быть обнаружены определяемыми пользователем обработчиками исключений, даже если они генерируются как исключения с собственным кодом исключения (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»)

0 голосов
/ 07 декабря 2011

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

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

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

(см. Также потрясающий комментарий Ганса выше)

...