log4cpp:关于SIGSEGV的两个问题

时间:2015-06-08 13:48:46

标签: c++ sigsegv

我正在开发Linux下的cpp项目,我想构建一个日志系统,将一些重要信息写入文件。所以我使用这个图书馆:log4cpp

这是关于log4cpp的代码:

// class Log head file
class Log
{
public:
    explicit Log(const char * infoCategory = nullptr, const string & pattern = string("%d: %p %c %x: %m%n"), const char * filename = "log")
    : category(infoCategory == nullptr ? Category::getRoot() : Category::getRoot().getInstance(infoCategory))
    {
        logFile.open(filename, ios::app);
        osAppender = new OstreamAppender("osAppender", &logFile);
        patternLayout = new PatternLayout();
        patternLayout->setConversionPattern(pattern);
        osAppender->setLayout(patternLayout);
        category.addAppender(osAppender);
        logFile.seekp(0, ios::end);
        size = logFile.tellp();
    }
    ~Log()
    {
        category.shutdown();
        logFile.close();
        // Do NOT delete osAppender and patternLayout
    }
    void info(const string & info)
    {
        category.info(info);
    }
private:
    ofstream logFile;
    streampos size;
    Category & category;
    OstreamAppender * osAppender;
    PatternLayout * patternLayout;
};

现在,我可以使用Log写下一些内容。例如,有一个类代理,如下所示:

#include "Log.h"
class Agent
{
public:
    ~Agent()
    {
        terminate();
    }
    void initialize()
    {
        log.info(" initialized.");
    }
    void terminate()
    {
        log.info(" terminated.");
    }
    static Agent & getInstance()
    {
        static Agent agent;
        return agent;
    }
    Agent()
    {
    }
private:
    Log log;
};

函数getInstance用于生成“Singleton”。它的构造函数是私有的,因此我们必须调用getInstance来生成一个对象。由于此对象是静态的,因此它只能初始化一次。 现在在main,我写了这个:

int main()
{
    Agent & agent = Agent::getInstance();
    agent.initialize();
    return 0;
}

现在如果我运行它,项目将停在函数Log::info中,我将收到此错误:Signal received: SIGSEGV(Segmentation fault)
令我惊讶的是,如果我删除log.info("terminated.");或删除log.info("initialized");,或者我将两个info移到initializeterminate函数中,则错误将消失。
或者,如果我在函数Agent中初始化正常main,则表示我不使用getInstance,而是执行此操作:Agent agent;,错误将消失太。
或者,如果我在函数Agent中新建getInstance,而不是使用static,则错误也会消失。
这是我的第一个问题。

我的第二个问题在这里:
请注意,Log的析构函数中有注释:
// do NOT delete osAppender and patternLayout

我提出了这样的评论,因为我认为它们都是来自new的指针,所以我可以而且应该删除它们。但如果我删除其中一个或两个,我会收到同样的错误:
Signal received:SIGSEGV

1 个答案:

答案 0 :(得分:0)

问题解决了。
我遇到了这个问题,因为logagent都是静态的 这意味着它们在函数return 0;main之后将是免费的,我们无法决定免费的顺序。
在这种情况下,显然在调用agent的虚函数之前,log已经空闲,因此当我在虚函数中调用terminate()时,会出现错误。