背景
在我的C ++程序中,我有一个SIGALRM处理程序,我想通过执行抛出将信号转换为异常(我明白这通常不是一个好习惯,但在系统中我正在研究它&#39 ; s可能是唯一的选择)。我的问题是我们在执行malloc时可以调用SIGALRM处理程序,而throw会调用__cxa_allocate_exception来执行另一个malloc。两个malloc调用可以在glibc 2.12中遇到死锁。我尝试预先分配异常,但仍然发生了对__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。
问题
我的问题是:无论如何我可以阻止扔掉调用malloc吗? (另外,据我所知,当我做一个malloc时我可以阻止SIGALRM信号,但我担心有太多的地方需要阻止)。
提前致谢。任何帮助/参考都非常受欢迎。
答案 0 :(得分:1)
一般问题是,如果在任何异步不安全库函数(例如malloc或printf)中调用信号处理程序,跳出信号处理程序(通过longjmp或异常)可能会使glibc处于不一致状态状态,下次你打电话时会崩溃或行为不端。
因此,即使你能够在异常设置中避免调用malloc,并抛出异常并捕获并处理它,你的程序也会在下次调用malloc时崩溃。
避免这种情况的唯一方法是确保在async-unsafe库函数中无法调用信号处理程序。您可以使用sigblock
阻止和解除对程序中任何一个信号不安全功能的调用周围的信号:
oldmask = sigblock(SIGALRM);
...call to malloc or printf or whatever...
setsetmask(oldmask);
这是可能的,但不是非常实用。
答案 1 :(得分:-1)
手册指出malloc是“AS-Unsafe”,这意味着在asychronous signal handlers内调用它是不安全的。如果你这样做,你的程序有不确定的行为。