Windows 应用程序如何处理分段错误?“处理”是指拦截它们并可能输出描述性消息。此外,从它们中恢复的能力也很好,但我认为这太复杂了。
6 回答
让它们崩溃并让 Windows 错误报告处理它 - 在 Vista+ 下,您还应该考虑注册重新启动管理器,这样您就有机会保存用户的工作并重新启动应用程序(如 Word/Excel/etc..做)
使用SEH进行早期异常处理,并使用SetUnhandledExceptionFilter显示描述性消息。
如果您添加/EHa
编译器参数,那么try {} catch(...)
将为您捕获所有异常,包括 SEH 异常。
您还可以使用__try {} __except {}
which 在捕获异常时为您提供更大的灵活性。__try {} __except {}
在你的整个函数上加上一个在main()
某种程度上相当于使用SetUnhandeledExceptionFilter()
.
话虽如此,您还应该使用正确的术语。“seg-fault”是一个 UNIX 术语。Windows 上没有分段错误。在 Windows 上,它们被称为“访问冲突异常”
你想在这里做什么取决于你关心什么样的故障。如果您的代码很草率,容易出现或多或少随机的一般保护违规行为,那么@Paul Betts 的答案就是您所需要的。
如果您的代码有充分的理由尊重坏指针,并且您想恢复,请从@whunmr 关于 SEH 的建议开始。如果您对代码有足够清晰的控制,可以准确地知道它在故障点处于什么状态以及如何进行恢复,那么您可以处理并确实恢复。
关于如何使用的 C++ 自包含示例SetUnhandledExceptionFilter
,触发写入错误并显示漂亮的错误消息:
#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;
}