C ++:使用segvcatch安全吗?

编程入门 行业动态 更新时间:2024-10-13 22:21:36
本文介绍了C ++:使用segvcatch安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我刚刚绊倒了 segvcatch 图书馆,该图书馆承诺包装segfaults和浮点错误到适当的异常。

如果我添加所有segfaults捕获的前提条件只会是空指针访问(即没有数组溢出)或无效的指针,这可能会在分裂之前完全清除内存,从而导致未定义的行为)?在捕获nullptr segfault后,程序是否仍然具有定义的语义?浮点错误怎么办?他们的行为是否更好/不同?

Sidenote:请不要发表任何意见,指出任何生成segfault的程序都是不正确的,应该被调试/修复。我知道我同意。不过,我对这个问题感兴趣。

解决方案

不安全

<信号处理程序非常简单,它们是错误的。这是SEGV处理程序:

void default_segv() { throw std :: runtime_error(Segmentation故障); }

这是非常非法的,至少在POSIX上。从信号处理程序中抛出异常是非常非常糟糕的主意。

附录 那么为什么这样一个糟糕的想法?

使用SIGALRM,它比一个坏主意更糟糕;它是未定义的行为,因为报警是异步的。使用SIGSEGV和SIGBUS,这是一个非常糟糕的主意。有其他信号,这只是一个坏主意。有时可能会起作用。其他时候,可能没有。结果可能是非常灾难性的,当魔法不起作用。

我会先看看SEGV。分段违例和总线错误的一个常见原因是捣毁堆栈。如果这是信号的原因,没有堆叠放松。 throw 将尝试展开堆栈,这将提高另一个SEGV。怎么办?在我的电脑上,这是一场灾难。

无论信号如何,投入信号处理程序对于RAII来说都不安全,因为 free (因此 delete )在处理程序的上下文中调用是不安全的。在信号处理程序的上下文中,有一大堆功能是不安全的。处理程序中 throw 之后发生的一切都是在信号处理程序的上下文中完成的,因为 throw 从处理程序返回。 throw 绕过回报。

这些不安全的电话和不安全的退绕意味着可以提高一个新的信号仍然处理那个老信号。这种递归信号是非常有问题的。例如,在我的电脑上,信号变成了SIGSTOP。程序不退出,它不会掉线的。它只是挂在那里,永久冻结,直到我杀死-9或重新启动机器。

I just stumbled upon the segvcatch library which promises to wrap segfaults and floating point errors into appropriate exceptions.

Is using this library safe, if I add the precondition that all segfaults caught will only be null pointer accesses (i.e., no array overflows or invalid pointers which could have screwed up the memory completely before segfaulting, resulting in undefined behaviour anyway)? Will the program still have defined semantics after catching a nullptr segfault? What about floating point errors? Do they behave better/different?

Sidenote: Please no comments stating that any program producing a segfault is ill-formed anyway and should be debugged/fixed. I know that and I agree. Still, I am interested in this question.

解决方案

Not safe.

The signal handlers are very simple, and they are simply wrong. Here's the SEGV handler:

void default_segv() { throw std::runtime_error("Segmentation fault"); }

That is quite illegal, at least on POSIX. Throwing an exception from within a signal handler is a very, very bad idea.

Addendum So why is this a bad idea?

With SIGALRM, it's worse than a bad idea; it's undefined behavior because alarms are asynchronous. With SIGSEGV and SIGBUS it's an extremely bad idea. With other signals, it's merely a bad idea. It might work, sometimes. Other times, it might not. Results can be quite disastrous when the magic doesn't work.

I'll look at SEGV first. One common cause of segmentation violations and bus errors is smashing the stack. There is no stack to unwind if this was the cause of the signal. The throw will try to unwind the stack, which will raise another SEGV. Now what? On my computer, that's a disaster.

Regardless of the signal, throwing inside a signal handler is not safe with respect to RAII because free() (and hence delete) is not safe to call within the context of a handler. There are a whole slew of functions that aren't safe to call from within the context of a signal handler. Everything that happens after the throw in the handler is done from within the context of the signal handler because the throw doesn't return from the handler. The throw bypasses the return.

Those unsafe calls and the unsafe unwinding means that a new signal can be raised while still handling that old signal. This recursive signal is highly problematic. On my computer, for example, the signal gets changed to SIGSTOP. The program doesn't exit, it doesn't drop core. It just hangs there, permanently frozen until I either kill -9 it or reboot the machine.

更多推荐

C ++:使用segvcatch安全吗?

本文发布于:2023-11-14 20:07:12,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1588402.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:segvcatch

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!