У меня есть ситуация, когда приложение, которое использует SetUnhandledExceptionFilter (через google breakpad ) для настройки обработчика пользовательских исключений, зависает после того, как обработчик исключений breakpad обнаружил сбой, сохранил файл мини-дамп и возвратил EXCEPTION_EXECUTE_HANDLER из функции SetUnhandledExceptionFilter, чтобы выполнить стандартный обработчик исключений. Зависание также происходит, если функция фильтра возвращает EXCEPTION_CONTINUE_SEARCH и диалоговое окно отчета об ошибках Windows было отключено с помощью SetErrorMode (). Если SetErrorMode () не используется для отключения WER, процесс закрывается, когда пользователь нажимает кнопку «Закрыть» в диалоговом окне WER.
Зависание происходит под Windows XP, но не под Windows 7.
Документация для SetUnhandledExceptionFilter гласит, что при возврате 'EXECEPTION_EXECUTE_HANDLER' будет выполняться связанный обработчик исключений, который "обычно приводит к завершению процесса", но я не смог найти документацию по используемому методу завершения.
Трассировка стека показывает, что зависание происходит в глобальном деструкторе для объекта в сторонней DLL, вызываемой из прелюдии DllMain ().
ntdll.dll!_KiFastSystemCallRet@0()
ntdll.dll!_NtWaitForSingleObject@12() + 0xc bytes
kernel32.dll!_WaitForSingleObjectEx@12() + 0x8b bytes
kernel32.dll!_WaitForSingleObject@8() + 0x12 bytes
QtCore4.dll!QWaitCondition::wait(QMutex * mutex=0x03ad1b00, unsigned long time=4294967295) Line 175 + 0x15 bytes C++
QtCore4.dll!QThreadPoolPrivate::waitForDone() Line 295 + 0x10 bytes C++
QtCore4.dll!QThreadPool::~QThreadPool() Line 429 C++
QtCore4.dll!QThreadPool::`vector deleting destructor'() + 0x3d bytes C++
QtCore4.dll!`theInstance'::`8'::`dynamic atexit destructor for 'cleanup''() + 0x14 bytes C++
QtCore4.dll!_CRT_INIT(void * hDllHandle=0x02b2b2d0, unsigned long dwReason=45265416, void * lpreserved=0x02b2b208) Line 446 C
QtCore4.dll!__DllMainCRTStartup(void * hDllHandle=0x67000000, unsigned long dwReason=0, void * lpreserved=0x00000000) Line 557 + 0x8 bytes C
QtCore4.dll!_DllMainCRTStartup(void * hDllHandle=0x67000000, unsigned long dwReason=0, void * lpreserved=0x00000001) Line 507 + 0xe bytes C
ntdll.dll!_LdrpCallInitRoutine@16() + 0x14 bytes
ntdll.dll!_LdrShutdownProcess@0() - 0xfe bytes
kernel32.dll!__ExitProcess@4() + 0x42 bytes
kernel32.dll!7c81cb0e()
kernel32.dll!_BaseThreadStart@8() + 0x2f479 bytes
Полагаю, что мьютекс был заблокирован потоком, который с тех пор был убит, но я могу представить себе другие виды глобальных ctors / dtors, которые могут быть выполнены таким образом, что вызовет подобную проблему. Мои вопросы:
- Ожидается ли поведение
ExitProcess()
, вызываемое в случае сбоя, если WER отключен через SetErrorMode()
?
- Кто-нибудь знает об изменениях в поведении обработчиков исключений по умолчанию между Windows XP и Windows 7, которые могут иметь значение?
- Если
ExitProcess()
- ожидаемое поведение, каков самый безопасный способ решения этой проблемы в сторонних DLL? Вызов TerminateProcess()
из обработчика исключений breakpad решает проблему, но есть ли какие-то предупреждения, о которых я должен знать?