C ++:使用segvcatch安全吗? [英] C++: Is using segvcatch safe?

查看:184
本文介绍了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安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆