Hi Curt,
I was reading your
http://www.opensubscriber.com/message/[email protected]/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.