【发布时间】:2016-05-25 00:20:24
【问题描述】:
背景
在我的 C++ 程序中,我有一个 SIGALRM 处理程序,我想在其中通过 throw 将信号转换为异常(我知道这通常不是好的做法,但在我正在处理的系统中,它可能是唯一的选择)。我的问题是,当我们执行 malloc 时,可能会调用 SIGALRM 处理程序,而 throw 将调用执行另一个 malloc 的 __cxa_allocate_exception。在 glibc 2.12 中,这两个 malloc 调用可能会遇到死锁。我尝试预先分配异常,但对 __cxa_allocate_exception 的调用仍然发生。我检查了 gcc 的源代码,似乎没有任何条件可以进行 __cxa_allocate_exception 调用。
附加背景
我在 try 块之前安装信号处理程序,并在 catch 之后将其卸载。我是从信号处理程序中抛出的,这样我认为它将在 try 块内(我们不考虑在 catch 逻辑中接收到信号的情况)并且可以正确捕获。
我想我遇到了这里描述的 malloc 死锁:https://sourceware.org/bugzilla/show_bug.cgi?id=13699 和这里 https://sourceware.org/ml/libc-alpha/2012-02/msg00272.html。
问题
我的问题是:无论如何我可以阻止 throw 调用 malloc 吗? (另外,我知道我在做malloc的时候可以阻塞SIGALRM信号,但是我怕阻塞的地方太多了)。
提前致谢。任何帮助/参考都非常感谢。
【问题讨论】:
-
你打算如何捕捉你抛出的异常?
-
如果您在析构函数内、在
noexcept函数期间或在另一个异常处于活动状态时收到此信号会发生什么? -
“将信号转换为异常”?这怎么可能?当信号发生时,信号处理程序不会在任何地方调用 from,因此无法捕获异常。还是我缺少什么?
-
布赖恩是对的。您究竟希望堆栈在哪里展开?即使实现以某种方式将堆栈展开到异常处理程序,当您从处理信号返回时,程序将如何处理现在无效的堆栈?为什么要这样惩罚自己?
-
信号处理程序可以异步执行(除非通过专门调用
raise调用)