2015-06-08 2 views
0

Я работаю над проектом cpp под Linux, и я хочу создать систему журналов для записи важной информации в файл. Поэтому я использую этот 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 является для создания «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 в функцию initialize или terminate, ошибка исчезнет.
Или, если я инициализирую нормальный Agent в функции main, я имею в виду, что я не использую getInstance, вместо этого я делаю это: Agent agent;, ошибка также исчезнет.
Или, если я новичок Agent в функции getInstance, вместо использования static ошибка также исчезнет.
Это мой первый вопрос.

Мой второй вопрос здесь:
Пожалуйста, обратите внимание, что комментарий в деструкторе Log:
// do NOT delete osAppender and patternLayout

я поставил такой комментарий, потому что я думаю, что оба они являются указателями, которые приходят из new, поэтому я мог и должен их удалить. Но если я удалю один из них или оба из них, я получу ту же ошибку:
Signal received:SIGSEGV.

+0

Если кто-то работает под Linux тоже, можете ли вы установить log4cpp и сделать тест для меня? – Yves

ответ

0

Проблема решена.
У меня эта проблема, потому что log и agent здесь все статические.
Это означает, что оба они будут бесплатными послеreturn 0; в функции main, и мы не можем решить порядок бесплатного.
В этом случае, очевидно, перед вызовом виртуальной функции agent, log был свободен, поэтому, когда я вызывал terminate() в виртуальную функцию, произошла ошибка.

Смежные вопросы