Hi Curt, I was reading your http://www.opensubscriber.com/message/log4cxx-u...@logging.apache.org/4931122.html post here and I think I understand what I might have done wrong to make it non-threadsafe (I too had made my logstream a data member). So here's the modification of my code (though it still seems to either throw an exception or crash at the end):
In my header file I have this: class myLog { public: ~myLog() {} // data member log4cxx::LoggerPtr rootLogger; protected: // only singleton (friend) will access this myLog(); // don't need arguments; configuration file does that private: // no copy ctor myLog(const myLog &other); // no assignment myLog &operator=(const myLog &other); friend class ACE_Singleton<myLog, ACE_Null_Mutex>; }; typedef ACE_Singleton<myLog, ACE_Null_Mutex> LogSingleton; #define MYLOG_FATAL log4cxx::logstream(LogSingleton::instance()->rootLogger, log4cxx::Level::getFatal()) #define MYLOG_ERROR log4cxx::logstream(LogSingleton::instance()->rootLogger, log4cxx::Level::getError()) #define MYLOG_WARN log4cxx::logstream(LogSingleton::instance()->rootLogger, log4cxx::Level::getWarn()) #define MYLOG_INFO log4cxx::logstream(LogSingleton::instance()->rootLogger, log4cxx::Level::getInfo()) #define MYLOG_TRACE log4cxx::logstream(LogSingleton::instance()->rootLogger, log4cxx::Level::getTrace()) #define MYLOG_DEBUG log4cxx::logstream(LogSingleton::instance()->rootLogger, log4cxx::Level::getDebug()) #define MYLOG_ENDL LOG4CXX_ENDMSG In the corresponding cpp file I have: using namespace std; using namespace log4cxx; using namespace log4cxx::xml; using namespace log4cxx::helpers; myLog::myLog():rootLogger(Logger::getRootLogger()) { // get configuration file for initial settings try { // Load configure file DOMConfigurator::configure("test.xml"); } catch (...) { std::cerr<<"Log4cxx initialization Error: "<<endl; abort(); } } Now this is the routine that I run in my threads: virtual int svc(void) { MYLOG_INFO << "I'm in the thread with name=" << name << MYLOG_ENDL; MYLOG_DEBUG << "And the \"this\" of this class is located at " << hex << this << dec << MYLOG_ENDL; // initialized random # generator srand(count); while (!shutdown) { unsigned int tmp=rand_r(&count); if (tmp%2==0) { MYLOG_ERROR << "All w0rk and nO pLAy mAkeS " << name << " A duLl gIrl" << MYLOG_ENDL; } else { MYLOG_INFO << tmp << " bottles of beer on the wall ..." << MYLOG_ENDL; } } return 0; } Now once I made logstream no longer a data member, I no longer get the collisions that I saw earlier. But I'm still observing a variation of exception/Segmentation run time behavior each time I run the application: 1. The stack when it throws a Mutex exception as it exits: [Thread 0x41401940 (LWP 7829) exited] [Thread 0x40a00940 (LWP 7828) exited] terminate called after throwing an instance of 'log4cxx::helpers::MutexException' what(): Mutex exception: stat = 22 Program received signal SIGABRT, Aborted. 0x000000387c630265 in raise () from /lib64/libc.so.6 (gdb) where #0 0x000000387c630265 in raise () from /lib64/libc.so.6 #1 0x000000387c631d10 in abort () from /lib64/libc.so.6 #2 0x00000038822becb4 in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib64/libstdc++.so.6 #3 0x00000038822bcdb6 in ?? () from /usr/lib64/libstdc++.so.6 #4 0x00000038822bcde3 in std::terminate() () from /usr/lib64/libstdc++.so.6 #5 0x00000038822bceca in __cxa_throw () from /usr/lib64/libstdc++.so.6 #6 0x00002aaaaafd3f8d in log4cxx::helpers::synchronized::synchronized (this=<value optimized out>, mutex1=<value optimized out>) at synchronized.cpp:35 #7 0x00002aaaaafe783d in log4cxx::WriterAppender::close (this=0x628110) at writerappender.cpp:135 #8 0x00002aaaaaf6d369 in log4cxx::FileAppender::~FileAppender (this=0x1e91, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at fileappender.cpp:88 #9 0x00002aaaaaf3e3f8 in log4cxx::helpers::ObjectPtrT<log4cxx::Appender>::~ObjectPtrT (this=0x61e010, __in_chrg=<value optimized out>) at ../../../src/main/include/log4cxx/helpers/objectptr.h:100 #10 0x00002aaaaaf3e699 in _Destroy<log4cxx::helpers::ObjectPtrT<log4cxx::Appender> > (this=0x61e040, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_construct.h:107 #11 __destroy_aux<log4cxx::helpers::ObjectPtrT<log4cxx::Appender>*> (this=0x61e040, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_construct.h:122 #12 _Destroy<log4cxx::helpers::ObjectPtrT<log4cxx::Appender>*> (this=0x61e040, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_construct.h:155 #13 _Destroy<log4cxx::helpers::ObjectPtrT<log4cxx::Appender>*, log4cxx::helpers::ObjectPtrT<log4cxx::Appender> > (this=0x61e040, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_construct.h:182 #14 ~vector (this=0x61e040, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_vector.h:272 #15 log4cxx::helpers::AppenderAttachableImpl::~AppenderAttachableImpl (this=0x61e040, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at ../../../src/main/include/log4cxx/helpers/appenderattachableimpl.h:46 #16 0x00002aaaaaf8ecfc in ~ObjectPtrT (this=0x61be10, __vtt_parm=<value optimized out>, __in_chrg=<value optimized out>) at ../../../src/main/include/log4cxx/helpers/objectptr.h:100 #17 log4cxx::Logger::~Logger (this=0x61be10, __vtt_parm=<value optimized out>, __in_chrg=<value optimized out>) at logger.cpp:55 #18 0x00002aaaaafc2521 in log4cxx::spi::RootLogger::~RootLogger (this=0x1e91, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at ../../../src/main/include/log4cxx/spi/rootlogger.h:37 #19 0x0000000000403b48 in ~ObjectPtrT (this=0x619c50, __in_chrg=<value optimized out>) at /usr/local/include/log4cxx/helpers/objectptr.h:100 #20 ~myLog (this=0x619c50, __in_chrg=<value optimized out>) at mylog.h:11 #21 ACE_Singleton<myLog, ACE_Null_Mutex>::~ACE_Singleton (this=0x619c50, __in_chrg=<value optimized out>) at /home/zcasilum/ACE_wrappers/ace/Singleton.h:80 #22 0x0000000000403642 in ACE_Singleton<myLog, ACE_Null_Mutex>::cleanup (this=0x619c50) at /home/zcasilum/ACE_wrappers/ace/Singleton.cpp:112 #23 0x00002aaaaab76b60 in ACE_OS_Exit_Info::call_hooks (this=<value optimized out>) at ../../ace/Cleanup.cpp:166 #24 0x00002aaaaabbd4a4 in ACE_Object_Manager::fini (this=0x60a6f0) at ../../ace/Object_Manager.cpp:726 #25 0x00002aaaaabbd6b8 in ACE_Object_Manager::~ACE_Object_Manager (this=0x1e91, __in_chrg=<value optimized out>) at ../../ace/Object_Manager.cpp:417 #26 0x00002aaaaabbd863 in ACE_Object_Manager_Manager::~ACE_Object_Manager_Manager (this=<value optimized out>, __in_chrg=<value optimized out>) at ../../ace/Object_Manager.cpp:882 #27 0x000000387c63368e in __cxa_finalize () from /lib64/libc.so.6 #28 0x00002aaaaab5b636 in __do_global_dtors_aux () from /usr/local/lib/libACE-5.8.so #29 0x0000000000000000 in ?? () 2. The stack when it crashes as it's running and NOT as the executable exits: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x40a00940 (LWP 7927)] 0x00002aaaaaf8ca1c in log4cxx::Logger::isEnabledFor (this=0x2aaaac000940, level1=...) at logger.cpp:287 287 if(repository == 0 || repository->isDisabled(level1->toInt())) (gdb) where #0 0x00002aaaaaf8ca1c in log4cxx::Logger::isEnabledFor (this=0x2aaaac000940, level1=...) at logger.cpp:287 #1 0x00002aaaaaf97079 in log4cxx::logstream_base::logstream_base (this=0x409ff790, log=<value optimized out>, lvl=...) at logstream.cpp:47 #2 0x00002aaaaaf97349 in log4cxx::logstream::logstream (this=0x61bd00, logger=..., level=...) at logstream.cpp:181 #3 0x0000000000403bfd in handler::svc (this=0x7fffffffe3b0) at threadtest.cpp:24 #4 0x00002aaaaac02017 in ACE_Task_Base::svc_run (args=<value optimized out>) at ../../ace/Task.cpp:275 #5 0x00002aaaaac02f95 in ACE_Thread_Adapter::invoke (this=0x611610) at ../../ace/Thread_Adapter.cpp:98 #6 0x000000387d20673d in start_thread () from /lib64/libpthread.so.0 #7 0x000000387c6d3d1d in clone () from /lib64/libc.so.6 So that line 24 in the handler::svc is MYLOG_INFO << "I'm in the thread with name=" << name << MYLOG_ENDL; So do you know what I'm doing wrong here? Why the variation of exception/segmentation fault behavior? Just so you know what the patch I had put in as advised at the top of this thread, I replaced ObjectPtrBase::exchange with the following code: void* ObjectPtrBase::exchange(void** destination, void* newValue) { #if _WIN32 && (!defined(_MSC_VER) || _MSC_VER >= 1300) return InterlockedExchangePointer(destination, newValue); #elif APR_SIZEOF_VOIDP == 4 return (void*) apr_atomic_xchg32((volatile apr_uint32_t*) destination, (apr_uint32_t) newValue); #else void* oldValue = *destination; *destination = newValue; return oldValue; apr_atomic_xchgptr((volatile void**)destination, newValue); #endif } And built it with the CFLAGS="-fPIC" option. So where am I going wrong here? Thanks! Jade -- View this message in context: http://old.nabble.com/log4cxx-0.10.0%3A-Fix-for-64-bit-only-thread-safety-bug-in-ObjectPtrBase-tp21504865p29221033.html Sent from the Log4cxx - Dev mailing list archive at Nabble.com.