Windows下如何处理段错误?
Windows 应用程序如何处理分段错误?我所说的“处理”是指拦截它们并可能输出一条描述性消息。另外,从它们中恢复的能力也很好,但我认为这太复杂了。
How can a Windows application handle segmentation faults? By 'handle' I mean intercept them and perhaps output a descriptive message. Also, the ability to recover from them would be nice too, but I assume that is too complicated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(6)
如果您添加 /EHa
编译器参数,则 try {} catch(...)
将为您捕获所有异常,包括 SEH 异常。
您还可以使用 __try {} __ except {}
,它可以让您更灵活地了解捕获异常时要执行的操作。将 __try {} __ except {}
放在整个 main()
函数上与使用 SetUnhandeledExceptionFilter()
有点等效。
话虽这么说,您还应该使用正确的术语:“seg-fault”是一个 UNIX 术语。 Windows 上不存在分段错误。在 Windows 上,它们被称为“访问冲突异常”
有关如何使用 SetUnhandledExceptionFilter
、触发写入错误并显示一条不错的错误消息的 C++ 自包含示例:
#include <windows.h>
#include <sstream>
LONG WINAPI TopLevelExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
{
std::stringstream s;
s << "Fatal: Unhandled exception 0x" << std::hex << pExceptionInfo->ExceptionRecord->ExceptionCode
<< std::endl;
MessageBoxA(NULL, s.str().c_str(), "my application", MB_OK | MB_ICONSTOP);
exit(1);
return EXCEPTION_CONTINUE_SEARCH;
}
int main()
{
SetUnhandledExceptionFilter(TopLevelExceptionHandler);
int *v=0;
v[12] = 0; // should trigger the fault
return 0;
}
已使用 g++
成功测试(并且也应该可以与 MSVC++ 一起使用)
与 Jean-François Fabre 解决方案类似,但使用 MinGW-w64 中的 Posix 代码。但请注意,程序必须退出 - 它无法从 SIGSEGV 中恢复并继续。
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void sigHandler(int s)
{
printf("signal %d\n", s);
exit(1);
}
int main()
{
signal(SIGSEGV, sigHandler);
int *v=0;
*v = 0; // trigger the fault
return 0;
}
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
让它们崩溃并让 Windows 错误报告处理它 - 在 Vista+ 下,您还应该考虑注册重新启动管理器 (http://msdn.microsoft.com/en-us/library/aa373347(VS.85).aspx),这样就有机会省出来用户的工作并重新启动应用程序(就像 Word/Excel/etc.. 所做的那样)
Let them crash and let the Windows Error Reporting handle it - under Vista+, you should also consider registering with Restart Manager (http://msdn.microsoft.com/en-us/library/aa373347(VS.85).aspx), so that you have a chance to save out the user's work and restart the application (like what Word/Excel/etc.. does)