2015-06-08 45 views
0

我正在研究Linux下的cpp項目,我想構建一個日誌系統來將一些重要信息寫入文件。所以我用這個libraty:log4cpp
log4cpp:有關SIGSEGV的兩個問題

這裏是我的代碼約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是產生了「單身」。它的構造函數是私有的,所以我們必須調用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,錯誤就會消失。
或者,如果我在函數main中初始化一個正常的Agent,我的意思是我沒有使用getInstance,而是我這樣做:Agent agent;,錯誤也會消失。
或者,如果我在功能getInstance新的Agent,而不是使用static,錯誤就會消失了。
這是我的第一個問題。

我的第二個問題是在這裏:
請注意,在Log析構函數評論:
// do NOT delete osAppender and patternLayout

我把這樣的評論,因爲我覺得他們兩個是它們來自指針new,所以我可以並應該刪除它們。但是如果我刪除其中一個或它們兩個,我會得到相同的錯誤:
Signal received:SIGSEGV

+0

如果有人也在Linux下工作,你可以安裝log4cpp併爲我做一個測試嗎? – Yves

回答

0

問題已解決。
我得到這個問題,因爲logagent這裏都是靜態的。
這意味着他們兩個將在return 0;之後免費在功能main之後,我們不能決定免費的順序。
在這種情況下,agent的虛函數被調用之前明顯的log一直是免費的,所以,當我在虛擬函數調用terminate(),會有一個錯誤。