SetUnhandledExceptionFilter и обработчик исключений по умолчанию, когда диалоговое окно отчета о сбое отключено - PullRequest
2 голосов
/ 24 ноября 2011

У меня есть ситуация, когда приложение, которое использует 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 решает проблему, но есть ли какие-то предупреждения, о которых я должен знать?

1 Ответ

0 голосов
/ 27 сентября 2012

Чтобы ответить «Что изменилось между XP и Windows 7», может иметь отношение следующее: «Случай исчезновения исключения OnLoad - исключения обратного вызова пользовательского режима в x64», http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/.

...