windows Windows下如何处理段错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1992816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to handle seg faults under Windows?
提问by Nathan Osman
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.
Windows 应用程序如何处理分段错误?通过“处理”,我的意思是拦截它们并可能输出描述性消息。此外,从它们中恢复的能力也很好,但我认为这太复杂了。
采纳答案by whunmr
Use SEHfor early exception handling, and use SetUnhandledExceptionFilterto show a descriptive message.
使用SEH进行早期异常处理,并使用SetUnhandledExceptionFilter显示描述性消息。
回答by Ana Betts
Let them crash and let the Windows Error Reporting handle it - under Vista+, you should also consider registering with Restart Manager, so that you have a chance to save out the user's work and restart the application (like what Word/Excel/etc.. does)
让它们崩溃并让 Windows 错误报告处理它 - 在 Vista+ 下,您还应该考虑注册 Restart Manager,以便您有机会保存用户的工作并重新启动应用程序(例如 Word/Excel/etc..做)
回答by shoosh
If you add the /EHa
compiler argument then try {} catch(...)
will catch all exceptions for you, including SEH exceptions.
You can also use __try {} __except {}
which gives you more flexibility on what to do when an exception is caught. putting an __try {} __except {}
on your entire main()
function is somewhat equivalent to using SetUnhandeledExceptionFilter()
.
如果您添加/EHa
编译器参数,则将try {} catch(...)
为您捕获所有异常,包括 SEH 异常。
您还可以使用__try {} __except {}
which 使您在捕获异常时更灵活地执行操作。将 an__try {} __except {}
放在整个main()
函数上有点等同于使用SetUnhandeledExceptionFilter()
.
That being said, you should also use the proper terminology. "seg-fault" is a UNIX term. there are no segmentation faults on windows. On windows they are called "Access Violation exceopnts"
话虽如此,您还应该使用正确的术语。“seg-fault”是一个 UNIX 术语。Windows 上没有分段错误。在 Windows 上,它们被称为“访问冲突异常”
回答by Jean-Fran?ois Fabre
C++ self-contained example on how to use SetUnhandledExceptionFilter
, triggering a write fault and displaying a nice error message:
关于如何使用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;
}
Tested successfully with g++
(and should work OK with MSVC++ as well)
已成功测试g++
(并且也可以与 MSVC++ 一起使用)
回答by gbburkhardt
Similar to Jean-Fran?ois Fabre solution, but with Posix code in MinGW-w64. But note that the program must exit - it can't recover from the SIGSEGV and continue.
类似于 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;
}
回答by bmargulies
What you want to do here depends on what sort of faults you are concerned with. If you have sloppy code that is prone to more or less random General Protection Violations, then @Paul Betts answer is what you need.
你想在这里做什么取决于你关心什么样的故障。如果您的代码草率且容易出现或多或少的随机一般保护违规,那么@Paul Betts 的答案就是您所需要的。
If you have code that has a good reason to deference bad pointers, and you want to recover, start from @whunmr's suggestion about SEH. You can handle and indeed recover, if you have clear enough control of your code to know exactly what state it is in at the point of the fault and how to go about recovering.
如果您的代码有充分的理由来遵从坏指针,并且您想恢复,请从@whunmr 关于 SEH 的建议开始。如果您对代码有足够的控制权,可以准确地知道它在故障点处于什么状态以及如何进行恢复,那么您就可以处理并确实恢复。