我有一种情况,使用 SetUnhandledExceptionFilter (通过google breakpad)设置自定义异常处理程序的应用程序在 breakpad 异常处理程序发生崩溃后挂起,保存了一个小型转储文件并从 SetUnhandledExceptionFilter 函数返回 EXCEPTION_EXECUTE_HANDLER 执行标准异常处理程序。如果过滤器函数返回 EXCEPTION_CONTINUE_SEARCH 并且 Windows 错误报告对话框已通过 SetErrorMode() 禁用,也会发生挂起。如果不使用 SetErrorMode() 来禁用 WER,则一旦用户单击 WER 对话框中的“关闭”按钮,进程就会关闭。
挂起发生在 Windows XP 而不是 Windows 7 下。
SetUnhandledExceptionFilter的文档指出,当返回“EXECEPTION_EXECUTE_HANDLER”时,相关的异常处理程序将执行“通常导致进程终止”,但我找不到所使用的终止方法的文档。
堆栈跟踪显示挂起发生在第 3 方 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 中处理此问题的最安全方法是什么?从breakpad异常处理程序调用TerminateProcess()
解决了这个问题,但有什么我应该注意的警告吗?