在 Win32 上捕获 SIGSEGV 与在 Unix 上捕获 SIGSEGV 有何不同?
我正在编写需要在 Unix/Mac(使用 GCC)和 Win32(使用 mingw)上编译和运行而不会出现错误的代码。该代码必须在各种不同的环境中运行,并且它具有我无法控制的可加载模块,因此我通常使用 setjmp() 和 signal() 来保护每个模块。
我看到 WIN32 有 setjmp() 和 signal()。代码可以移植吗,还是我需要担心?
I am writing code that needs to compile and run without error on both Unix/Mac (with GCC) and on Win32 (with mingw). The code has to run in a wide variety of different environments and it has loadable modules that I can't control, so I typically protect each module with a setjmp() and signal().
I see that WIN32 has both setjmp() and signal(). Will the code work portably, or do I need to worry?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
继续担心吧。 CRT 应该模拟 signal(),但 MSVC 明确提到 longjmp() 在处理程序中是不合法的,除非它处理 SIGFPE。检查你的。
SIGSEGV 的等效项是 SEH 异常,异常代码为 0xc0000005 (STATUS_ACCESS_VIOLATION)。 MSVC 编译器允许使用 __try 和 __ except 关键字捕获它们。
像这样“保护”模块的想法是有严重缺陷的。您的程序状态已损坏且无法修复,您不知道它是如何变异的,因此您没有机会恢复它。继续跑步可能会导致许多事故。当它因另一个异常而死亡时,你会很幸运,让你不知道真正的问题是什么,但它更有可能只是生成长时间无法诊断的错误数据。你最好不要编写这样的代码。并在此过程中解决您的移植问题。
Go ahead and worry. The CRT should emulate signal() but the MSVC one explicitly mentions that longjmp() is not legal in a handler unless it handles SIGFPE. Check yours.
The equivalent of SIGSEGV is an SEH exception with exception code 0xc0000005 (STATUS_ACCESS_VIOLATION). The MSVC compiler allow catching them with the __try and __except keywords.
The idea of "protecting" a module like this is deeply flawed. Your program's state is corrupted beyond repair, you have no idea how it was mutated so you have no chance to restore it. Continuing to run can cause a number of mishaps. You'll be lucky when it dies on another exception, giving you no clue what the real problem was, but it is more likely to just generate bad data that won't be diagnosed for a long time. You are much better off just not writing code like this. And solve your porting problem in the process.