Francois Godin created AMQCPP-617:
-------------------------------------
Summary: Segfault when using a QueueBrowser.
Key: AMQCPP-617
URL: https://issues.apache.org/jira/browse/AMQCPP-617
Project: ActiveMQ C++ Client
Issue Type: Bug
Reporter: Francois Godin
Assignee: Timothy Bish
Priority: Critical
I encountered a rare (but that still happened a couple of time) crash due to
the ActiveMQ C++ library.
h2. Information
I've done some digging and the crash happen when the function
activemq::core::Browser::dispatch call
activemq::core::ActiveMQQueueBrowser::notifyMessageAvailable. The segfault
happen at the first member access in ActiveMQQueueBrowser.
h3. Core dump
#0 0x00007f38f7736758 in decaf::util::concurrent::Lock::lock() ()
from /home/Fasttracctest/daemon/FastTraccTestDaemon/lib/libactivemq-cpp.so.19
#1 0x00007f38f7736875 in
decaf::util::concurrent::Lock::Lock(decaf::util::concurrent::Synchronizable*,
bool) ()
from /home/Fasttracctest/daemon/FastTraccTestDaemon/lib/libactivemq-cpp.so.19
#2 0x00007f38f73f0f5d in
activemq::core::ActiveMQQueueBrowser::notifyMessageAvailable() ()
from /home/Fasttracctest/daemon/FastTraccTestDaemon/lib/libactivemq-cpp.so.19
#3 0x00007f38f73f4cd1 in
activemq::core::Browser::dispatch(decaf::lang::Pointer<activemq::commands::MessageDispatch,
decaf::util::concurrent::atomic::AtomicRefCounter> const&) ()
from /home/Fasttracctest/daemon/FastTraccTestDaemon/lib/libactivemq-cpp.so.19
#4 0x00007f38f7406c24 in
activemq::core::ActiveMQSessionExecutor::dispatch(decaf::lang::Pointer<activemq::commands::MessageDispatch,
decaf::util::concurrent::atomic::AtomicRefCounter> const&) ()
from /home/Fasttracctest/daemon/FastTraccTestDaemon/lib/libactivemq-cpp.so.19
#5 0x00007f38f7407ce5 in activemq::core::ActiveMQSessionExecutor::iterate() ()
from /home/Fasttracctest/daemon/FastTraccTestDaemon/lib/libactivemq-cpp.so.19
#6 0x00007f38f7543565 in activemq::threads::DedicatedTaskRunner::run() ()
from /home/Fasttracctest/daemon/FastTraccTestDaemon/lib/libactivemq-cpp.so.19
#7 0x00007f38f76acbef in ?? ()
from /home/Fasttracctest/daemon/FastTraccTestDaemon/lib/libactivemq-cpp.so.19
#8 0x00007f38f76ac964 in ?? ()
from /home/Fasttracctest/daemon/FastTraccTestDaemon/lib/libactivemq-cpp.so.19
#9 0x00007f38f9120aa1 in start_thread () from /lib64/libpthread.so.0
#10 0x00007f38f941eaad in ioperm () from /lib64/libc.so.6
#11 0x0000000000000000 in ?? ()
h3. Usage of the library
int getMessageCountInQueue(cms::Session* session, cms::Queue* queue) {
std::unique_ptr<cms::QueueBrowser>
browser(session->createBrowser(queue));
cms::MessageEnumeration* enumeration = browser->getEnumeration();
int count = 0;
while(enumeration->hasMoreMessages()) {
count++;
cms::Message* msg = enumeration->nextMessage();
delete msg;
}
return count;
}
h2. After some analysis, I have the following hypothesis:
It seems that when I destroy the ActiveMQQueueBrowser (and thus call
destroyConsumer), the Browser instance that refer to it may be kept alive by
activemq::core::ActiveMQSessionExecutor::dispatch (as it is stored in a
shared_ptr).
Often it is no problem as Browser::dispatch is not called but I guess it may
happen rarely and cause the segfault.
h2. Proposed solution
The basic ActiveMQConsumerKernel::dispatch should be protected against that
problem because it lock and check if the consumer is closed (which it is). It
just happen that the Browser::dispatch did not have those check and thus will
always execute the code.
As such, I propose splitting ActiveMQConsumerKernel::dispatch into two:
# The cleanup, locking and check into the new ActiveMQConsumerKernel::dispatch
# The operation itself into ActiveMQConsummerKernel::dispatchImpl.
Then, Browser only need to override dispatchImpl and will have the same
protection that ActiveMQConsumerKernel had.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)