无论如何,我可以阻止抛出调用malloc

时间:2016-05-25 00:20:24

标签: c++ exception-handling

背景

在我的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=13699https://sourceware.org/ml/libc-alpha/2012-02/msg00272.html

问题

我的问题是:无论如何我可以阻止扔掉调用malloc吗? (另外,据我所知,当我做一个malloc时我可以阻止SIGALRM信号,但我担心有太多的地方需要阻止)。

提前致谢。任何帮助/参考都非常受欢迎。

2 个答案:

答案 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内调用它是不安全的。如果你这样做,你的程序有不确定的行为。