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.

Reply via email to