Windows下如何处理段错误?

发布于 08-16 10:03 字数 81 浏览 7 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

庆幸我还是我2024-08-23 10:03:25

让它们崩溃并让 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)

感性2024-08-23 10:03:25

使用 SEH 进行早期异常处理,
并使用 SetUnhandledExceptionFilter 显示描述性消息。

Use SEH for early exception handling,
and use SetUnhandledExceptionFilter to show a descriptive message.

诠释孤独2024-08-23 10:03:25

如果您添加 /EHa 编译器参数,则 try {} catch(...) 将为您捕获所有异常,包括 SEH 异常。
您还可以使用 __try {} __ except {},它可以让您更灵活地了解捕获异常时要执行的操作。将 __try {} __ except {} 放在整个 main() 函数上与使用 SetUnhandeledExceptionFilter() 有点等效。

话虽这么说,您还应该使用正确的术语:“seg-fault”是一个 UNIX 术语。 Windows 上不存在分段错误。在 Windows 上,它们被称为“访问冲突异常”

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().

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 Exceptions"

花开浅夏2024-08-23 10:03:25

有关如何使用 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++ 一起使用)

C++ self-contained example on how to use SetUnhandledExceptionFilter, triggering a write fault and displaying a nice error message:

#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)

当梦初醒2024-08-23 10:03:25

您想要执行的操作取决于您所关心的故障类型。如果您的代码很草率,或多或少容易出现随机的一般保护违规行为,那么 @Paul Betts 的答案就是您所需要的。

如果您的代码有充分的理由遵循错误指针,并且您想要恢复,请从 @whunmr 关于 SEH 的建议开始。如果您对代码有足够清晰的控制,可以准确地知道故障时代码处于什么状态以及如何进行恢复,那么您就可以处理并确实恢复。

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.

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.

断爱2024-08-23 10:03:25

与 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; 
}

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.

#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; 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文