【问题标题】:How is catching SIGSEGV different on Win32 than on Unix?在 Win32 上捕获 SIGSEGV 与在 Unix 上有何不同?
【发布时间】:2010-10-19 12:19:10
【问题描述】:

我正在编写需要在 Unix/Mac(使用 GCC)和 Win32(使用 mingw)上编译和运行且没有错误的代码。代码必须在各种不同的环境中运行,并且它具有我无法控制的可加载模块,因此我通常使用 setjmp() 和 signal() 保护每个模块。

我看到WIN32 有setjmp() 和signal()。代码可以移植吗,还是我需要担心?

【问题讨论】:

    标签: winapi mingw signals


    【解决方案1】:

    放心吧。 CRT 应该模拟 signal() 但 MSVC 明确提到 longjmp() 在处理程序中是不合法的,除非它处理 SIGFPE。检查你的。

    SIGSEGV 的等价物是 SEH 异常,异常代码为 0xc0000005 (STATUS_ACCESS_VIOLATION)。 MSVC 编译器允许使用 __try 和 __except 关键字来捕获它们。

    像这样“保护”模块的想法存在严重缺陷。您的程序状态已损坏,无法修复,您不知道它是如何变异的,因此您没有机会恢复它。继续运行可能会导致许多事故。当它死于另一个异常时,你会很幸运,让你不知道真正的问题是什么,但它更有可能只是生成长时间无法诊断的坏数据。你最好不要写这样的代码。并在此过程中解决您的移植问题。

    【讨论】:

    • 感谢您的留言。我会尝试使用 __try 和 __except。我正在使用 try and catch(来自 C++),但它并没有达到我想要的效果。
    • 作为补充说明,通常我们遇到的问题不是写入错误,而是读取错误,而且最常见的原因是解码器信任了不应该信任的指针值。我知道这种方法存在严重缺陷,但不幸的是,它比其他方法更好。
    • 后续 -- __try 和 __except 在 mingw 下不起作用,但 SIGSEGV 在 mingw 上被 signal() 捕获。
    • 捕获 SIGSEGV / 0xC0000005 只有在处理程序中调用 system("mycrashreporter.exe") 是个好主意:) 就像 firefox 一样。除非您小心地保持全新状态并在崩溃处理程序中编写内存验证代码,否则不要尝试恢复或验证您的数据。写出这样的作品是艺术。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 2023-02-11
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多