在信号处理程序中打印回溯

时间:2019-03-13 18:17:44

标签: c++ linux synchronization signals

我面临同步主线程和信号处理程序之一的问题。

让我们考虑一下简单的课程:

class StackPrinter
{
    public:
        StackPrinter* Instance()
        {
            // Implemented classic singleton
        }

    private:
        std::vector<void*> PrintBacktrace(pthread_t threadId)
        {
            guard(someMutex);

            std::vector<void*> stack;
            _backtrace = &stack[0];

            // set up signal

            // kill thread so the signal will be raised

            // synchronise this thread with signalHandler with select and read methods

            return stack;
        }

    void** _backtrace;

    void signalHander(int sigNumber)
    {
        backtrace(_backtrace);

        // synchronise this thread with PrintBactrace with write method
    }
}

因此,此代码通常可以正常工作:我们发出一个信号,然后在signalHandler方法中处理它->通过写函数通知有关signalHandler方法中完成工作的通知->通过选择函数接收该通知,超时并可以继续进行...但是,例如,如果该线程(threadId)处于不间断状态,该怎么办?

我不会输入signalHandler方法,select()方法将收到超时,但是应用程序将在PrintBactrace方法中结束返回空向量堆栈的工作,并且我们不知道该线程是否不会更改其状态,因此当其他进程获得StackPrinter类的实例并尝试引发另一个信号时,signalHandler方法将最终执行。因此最后,当第一个进程仍想使用_backtrace数组时,另一个进程将使用_backtrace数组。

请记住,signalHandler方法中使用的所有内容都必须是异步信号安全(http://man7.org/linux/man-pages/man7/signal-safety.7.html)。

编辑: 有一会儿我有了一个静态映射的想法,其中键是线程,值可以是向量。 因此,我将裁撤void ** backtrace并将其粘贴到signalHandler函数中,所以它的唯一工作就是获取backtrace并将其放置在map中。如果它将在正常时间结束,则主线程将从映射中获取此向量-如果没有,则永远不会获得此数据。假设这种情况很少见,则不会有过多使用内存的风险。你觉得呢?

0 个答案:

没有答案