我们在Windows上,并且我们想要在应用程序出口的所有场景中出现故障转储(可能使用MiniDumpWriteDump
)。
到目前为止,我们已经确定并build立了以下内容:
SetUnhandledExceptionFilter
对于未处理的exception(Win32以及“正常”的C ++)。 _set_invalid_parameter_handler
_set_abort_behavior
加上一个SIGABRT
处理程序来说明对abort()
调用 有什么我们错过了吗? (模一些代码非法调用ExitProcess
, TerminateProcess
或其中一个exit
变体。)
我使用的是你已经列出的,加上_set_purecall_handler
,加上这个方便的代码片段:
void EnableCrashingOnCrashes() { typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags); typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags); static const DWORD EXCEPTION_SWALLOWING = 0x1; const HMODULE kernel32 = LoadLibraryA("kernel32.dll"); const tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy"); const tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy"); if(pGetPolicy && pSetPolicy) { DWORD dwFlags; if(pGetPolicy(&dwFlags)) { // Turn off the filter pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING); } } }
资料来源: http : //randomascii.wordpress.com/2012/07/05/when-even-crashing-doesnt-work/
在他的网站上的这些其他文章也帮助我了解这一点: http : //randomascii.wordpress.com/2011/12/07/increased-reliability-through-more-crashes/ http://randomascii.wordpress.com/2012/ 7月22日/更多的冒险,在-没有到崩溃正确/
SetUnhandledExceptionFilter强调不足以捕获所有意外退出。 如果应用程序不小心调用纯虚函数,则会弹出一个对话框。 应用程序将挂起,但不会崩溃。 既然没有例外,SetUnhandledExceptionFilter和WER都不能帮助。 这个主题有一些变化。
更糟糕的是,如果你在内核回调(比如WindowProc)中崩溃的话,那将是一个怪事。 如果在64位Windows上的32位应用程序中发生这种情况,则操作系统将捕获该异常,并继续执行。 是的,这个事故是无声无息的。 我觉得很可怕
高低顺序,简而言之:
_set*
函数, SetUnhandledExceptionFilter
就足够了。 abort
这样的C运行时函数将禁用全局异常处理程序,您可以使用SetUnhandledExceptionFilter
设置。 CRT将简单地调用这个相同的函数将NULL
参数,并且你的异常处理程序被禁用(不叫),如果CRT导致崩溃! 你可以做什么? [X] CreateToolhelp32Snapshot
和其他函数查找所有线程CreateToolhelp32Snapshot
。 寻找这个过程,并暂停所有其他正在运行的线程(当前除外)。 还有更多,我没有尝试(没有发现有用) – 向量异常处理。
另一种方法是将应用程序运行到调试器,您可以自己制作! 在调试器中,您可以捕获所有异常,就像VS调试器捕获的一样。 看我的文章 。 但是,你知道,这是不正确的做法。
编辑:只要阅读关于进程终止的最后一个内容。 你不应该控制这个。 在任何情况下,您都可以挂接所需的API,这将作为您的代码(如显示消息框)。
[X]您需要使用API挂钩。 我没有链接和细节方便。 你会挂钩其他相关的API,但主要是SetUnhandledExceptionFilter
(在你之后为你调用)。 您虚拟(挂钩)函数将如下所示:
xxx SetUnhandledExceptionFilter_DUMMY(xxx) { // Dont do any thing return NULL; }
我没有API挂钩的方便链接和细节。
为什么不试图让你的应用程序更安全?
我将添加一个解决方案,在Windows 7上运行时可以在某些情况下使用:
Windows错误报告(WER)提供了在应用程序崩溃时编写完整内存转储的选项。
所以,如果你没有问题的话,你只需要确保你真正感兴趣的崩溃情景会触发WER。 这真的让我们回到这个问题,但仍然…
您可以使用WER捕获任何异常。 正如你所看到的,CRT有时候会被叫做WER。
如果您想要始终在进程中捕获excpetion,则需要防止从CRT调用SetUnhandledExceptionFilter(NULL)
。 欲了解更多信息,请参阅我的博客条目: 改进“PreventSetUnhandledExceptionFilter”