2011-07-15 16 views
2

私はlog4cxxを使い始めました。 Visual Studio 2005でコンパイルしましたが、警告もエラーもありません。それは、グローバルロガーオブジェクトを破壊しようとしているときに、私は例外を取得するとき、私はアプリを閉じるまで期待通りに動作しますlog4cxxは〜Loggerの例外をスローしています

#includes<...> 
... 
... 
LoggerPtr logger(Logger::getLogger("MyApp")); 

void main(...) 
{ 
    //some logs here 
} 

:よう は基本的に見えます。ここ はトレースです:

log4cxx.dll!apr_pool_cleanup_kill(apr_pool_t * p=0xdddddddd, const void * data=0x01cf6158, int (void *)* cleanup_fn=0x10174250) Line 1981 + 0x3 bytes 
log4cxx.dll!apr_pool_cleanup_run(apr_pool_t * p=0xdddddddd, void * data=0x01cf6158, int (void *)* cleanup_fn=0x10174250) Line 2025 
log4cxx.dll!apr_thread_mutex_destroy(apr_thread_mutex_t * mutex=0x01cf6158) Line 133 
log4cxx.dll!log4cxx::helpers::Mutex::~Mutex() Line 57 
log4cxx.dll!log4cxx::Logger::~Logger() Line 55 + 0xb bytes 
log4cxx.dll!log4cxx::Logger::`vbase destructor'() + 0x19 bytes 
log4cxx.dll!log4cxx::Logger::`vector deleting destructor'() + 0x5a bytes 
log4cxx.dll!log4cxx::helpers::ObjectImpl::releaseRef() Line 46 + 0x39 bytes 
log4cxx.dll!log4cxx::Logger::releaseRef() Line 63 
log4cxx.dll!log4cxx::helpers::ObjectPtrT<log4cxx::Logger>::~ObjectPtrT<log4cxx::Logger>() Line 100 + 0x33 bytes 
NodeBHeartBeat.exe!`dynamic atexit destructor for 'logger''() + 0x2b bytes 
msvcr80d.dll!doexit(int code=0x00000000, int quick=0x00000000, int retcaller=0x00000001) Line 553 
msvcr80d.dll!_cexit() Line 413 + 0xb bytes 
msvcr80d.dll!__CRTDLL_INIT(void * hDllHandle=0x6c710000, unsigned long dwReason=0x00000000, void * lpreserved=0x00000001) Line 389 
msvcr80d.dll!_CRTDLL_INIT(void * hDllHandle=0x6c710000, unsigned long dwReason=0x00000000, void * lpreserved=0x00000001) Line 214 + 0x11 bytes 
ntdll.dll!774b9960() 

誰もが任意のアイデアなぜこれが起こっているを持っていますか?

class A 
{ 
public: 
    A() 
    { 
      string appPath = getenv("APPDIR"); 
      appPath = appPath + "/" + LOG4CXX_CONFIG_FILE_NAME; 

      // Load configuration file 
      DOMConfigurator::configure(appPath.c_str()); 
      m_serviceLogger = Logger::getLogger("tuxedoService"); 
    } 

    void log() 
    { 
     LOG4CXX_ERROR(m_serviceLogger, "This is a Test log"); 
    } 

private: 
    LoggerPtr m_serviceLogger; 
}; 

A a; 
int main() 
{ 
    a.log(); 
    return 0; 
} 

あなたはinit()のように、メンバ関数でコンストラクタを交換する場合、注意、およびログの前にメインでinit()にお電話ください:クラスの内部であなたのLoggerPtrを置く おかげ

答えて

1

は次のように、この問題を解決することができます関数では、説明したようにセグメントのエラーが発生します。

これは初期化シーケンスの問題です。

2

私は、単にロガーポインタに "0"を割り当てるだけで問題を回避することができました。

手品は、releaseRef()オブジェクト破壊順序を間接制御を与えているファイルSRC /メイン/含む/ log4cxx /ヘルパー/ objectptr.h

でlog4cxxソースコードの中に配置されます。

... 
    ... 
     ObjectPtrT& operator=(const int& null) //throw(IllegalArgumentException) 
      { 
        // 
        // throws IllegalArgumentException if null != 0 
        // 
        ObjectPtrBase::checkNull(null); 
        T* oldPtr = exchange(0); 
        if (oldPtr != 0) { 
         oldPtr->releaseRef(); 
        } 
        return *this; 
      } 
... 
... 

だから、あなたのコードのために、単に最後に行を追加します。私たちが持っていた似たようなケースで、ここでチャイムます

#includes<...> 
... 
... 
LoggerPtr logger(Logger::getLogger("MyApp")); 

void main(...) 
{ 
    //some logs here 

    logger = 0; // RELEASE REFERENCE TO POINTER 

    // Make sure no other reference to logger exist 
    // ie: a thread that used a copy constructor on the logger object. 
} 
0

。 log4cxx設定ファイルで定義されていないロガーを参照していました。ライブラリの一部のバージョンでは、これは大丈夫だったが、次のように他の人にそれがスタックトレースを引き起こした:

Program received signal SIGSEGV, Segmentation fault. 
0x0000000000000000 in ??() 
(gdb) bt 
#0 0x0000000000000000 in ??() 
#1 0x00007ffff72b3892 in std::_Rb_tree<std::string, std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> >, std::_Select1st<std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >, std::less<std::string>, std::allocator<std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > >::_M_erase(std::_Rb_tree_node<std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >*)() 
    from /usr/lib/liblog4cxx.so.10 
#2 0x00007ffff72b387b in std::_Rb_tree<std::string, std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> >, std::_Select1st<std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >, std::less<std::string>, std::allocator<std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > >::_M_erase(std::_Rb_tree_node<std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >*)() 
    from /usr/lib/liblog4cxx.so.10 
#3 0x00007ffff72b387b in std::_Rb_tree<std::string, std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> >, std::_Select1st<std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >, std::less<std::string>, std::allocator<std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > >::_M_erase(std::_Rb_tree_node<std::pair<std::string const, log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >*)() 
    from /usr/lib/liblog4cxx.so.10 
#4 0x00007ffff72b1a2a in log4cxx::Hierarchy::~Hierarchy()() from /usr/lib/liblog4cxx.so.10 
#5 0x00007ffff72b1c49 in log4cxx::Hierarchy::~Hierarchy()() from /usr/lib/liblog4cxx.so.10 
#6 0x00007ffff72c982a in log4cxx::spi::DefaultRepositorySelector::~DefaultRepositorySelector()() 
    from /usr/lib/liblog4cxx.so.10 
#7 0x00007ffff72c95bc in log4cxx::helpers::ObjectPtrT<log4cxx::spi::RepositorySelector>::~ObjectPtrT()() 
    from /usr/lib/liblog4cxx.so.10 
#8 0x00007ffff52e8e25 in __cxa_finalize() from /lib/x86_64-linux-gnu/libc.so.6 
#9 0x00007ffff727c2b6 in ??() from /usr/lib/liblog4cxx.so.10 
#10 0x000000000000005b in ??() 

をだから我々は、単に参照を削除しなければならなかったし、すべてが良かったです。それは非常に無害な見通しであった:

LoggerPtr logger(Logger::getLogger("someloggerthatdoesnotexist")); 
関連する問題