Обработка исключений завершения работы для Win32/C++

У меня есть процесс, который отлично обрабатывает исключения. Он вызывает:

_set_se_translator(exception_trans_func); 
SetUnhandledExceptionFilter(UnhandledExceptionFilterHandler);
_set_purecall_handler(purecallHandler);
set_terminate(terminateHandler);
set_unexpected(unexpectedHandler);
_set_invalid_parameter_handler(InvalidParameterHandler);
atexit(exitHandler); //ignored during an expected exit
_onexit(onexitHandler); //ignored during an expected exit

Каждый раз, когда происходит исключение, вызывается один из обработчиков, который создает аварийный дамп для меня. Жизнь хороша.

За исключением одного сайта заказчика. Когда они завершают процесс, возникает исключение, которое по какой-то причине не проходит через эти вызовы, и они получают ошибку:

Инструкция по адресу «0x101ba9df» ссылалась на память по адресу «0x00000004». Память не могла быть "прочитана". Нажмите OK, чтобы завершить....

Ссылка на память x000000004 выглядит так, как будто это нулевой указатель. И глядя на этот адрес, выглядит как деструктор глобального объекта STL (вероятно, в вызове initterm CRT, где очищаются глобальные переменные).

Сейчас я немного застрял, так как не могу получить диагностический дамп и стек вызовов и точно увидеть, что происходит. Так....

Почему исключение не направляется через указанные выше обработчики, а вместо этого отображается пользователю?

Есть ли способ скрыть этот диалог (поскольку в этот момент не причиняется никакого вреда)?

И есть ли способ отследить корневую ошибку?

Спасибо за любые идеи.


person DougN    schedule 25.11.2009    source источник


Ответы (3)


Какая операционная система у них работает?

Я предполагаю, что вы устанавливаете режим ошибки, используя что-то вроде

::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);

чтобы убедиться, что окна не прыгают со своей собственной обработкой ошибок?

person Len Holgate    schedule 26.11.2009
comment
Это именно то, что я после :) - person DougN; 27.11.2009
comment
Это действительно сработало? Диалог, который он описывает выше, звучит как диалог CRT, но вы используете вызов API Win32. - person Ana Betts; 28.11.2009

Это звучит так, как будто CRT поместил блок SEH try/catch (не может написать его правильно, срабатывает Markdown) вокруг некоторого фрагмента кода и перехватывает исключение для отображения сообщения, поэтому вы никогда не вызываете необработанный путь кода исключения. Возможно, вам придется взломать CRT, чтобы понять, что происходит.

person Ana Betts    schedule 25.11.2009

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

Я видел это с STL VS2008. Есть некоторые объекты блокировки STL, которые создаются через статический уровень файла во время запуска.

Используете ли вы STL в своих функциях обработки ошибок? Возможно, один из них срабатывает поздно при завершении работы программы и вызывает проблему.

person Len Holgate    schedule 25.11.2009
comment
Интересная идея. У меня были некоторые проблемы с объектами STL при запуске, поэтому выключение имеет смысл... - person DougN; 27.11.2009