Bug 1121615
| Summary: | An attempt to enqueue&dequeue a message with "too high priority" to a ring queue causes broker segfault | ||
|---|---|---|---|
| Product: | Red Hat Enterprise MRG | Reporter: | Pavel Moravec <pmoravec> |
| Component: | qpid-cpp | Assignee: | Alan Conway <aconway> |
| Status: | CLOSED ERRATA | QA Contact: | Jitka Kocnova <jkocnova> |
| Severity: | high | Docs Contact: | |
| Priority: | high | ||
| Version: | 2.5 | CC: | aconway, esammons, jkocnova, jross, lzhaldyb, mcressma, zkraus |
| Target Milestone: | 2.5.5 | ||
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | qpid-cpp-0.18-27 | Doc Type: | Bug Fix |
| Doc Text: |
It was discovered that if a message in a ring queue was given an invalid priority (greater than the maximum defined for that queue), an attempt to enqueue and dequeue it caused a segfault. Invalid priorities are now treated as equivalent to the maximum priority. The system no longer segfaults when processing messages with an invalid priority.
|
Story Points: | --- |
| Clone Of: | Environment: | ||
| Last Closed: | 2014-10-22 16:34:17 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
| Bug Depends On: | |||
| Bug Blocks: | 1140368, 1140369 | ||
|
Description
Pavel Moravec
2014-07-21 11:43:07 UTC
Updating..
Original segfault is _not_ present in 0.18-26, exactly due to the change introduced in -26:
-void RingQueuePolicy::enqueued(const QueuedMessage& m)
+void RingQueuePolicy::enqueued(const QueuedMessage& m, bool inUpdate)
{
uint priority = m.payload->getPriority();
assert(priority < queue.size());
- // Need to insert in correct location based on position
- typedef OrderedMessages::nth_index<0>::type MessageSeq;
- MessageSeq& seq = queue[priority].get<0>();
- MessageSeq::iterator i = lower_bound(seq.begin(), seq.end(), m);
- seq.insert(i, m);
+ if (inUpdate) {
+ // If this is an acquired message being enqueued during a cluster update
+ // then we need to ensure it goes in order by position.
+ typedef OrderedMessages::nth_index<0>::type MessageSeq;
+ MessageSeq& seq = queue[priority].get<0>();
+ MessageSeq::iterator i = lower_bound(seq.begin(), seq.end(), m);
+ seq.insert(i, m);
+ }
+ else {
+ // If this is a normal enqueue then we know it goes to the back of the
+ // queue, so avoid performance overhead of sorting.
+ queue[priority].push_back(m);
+ }
}
BUT 0.18-26 suffers by another segfault with reproducer (again, sending priority=10 is the key point):
qpid-config add queue q -b train2 --limit-policy=ring --max-queue-count=100 --flow-stop-count=0 --flow-stop-size=0 --argument=x-qpid-priorities=10
for i in $(seq 1 10); do
qpid-send -a q -m 1000 -b train2 --content-size=128 --priority=$i &
done
qpid-receive -a q -m 10000 -b train2 --print-content=no -f &
and backtrace:
#0 find<qpid::framing::SequenceNumber, boost::hash<qpid::framing::SequenceNumber>, std::equal_to<qpid::framing::SequenceNumber> > (
this=<value optimized out>, m=<value optimized out>, q=..., remove=false) at /usr/include/boost/multi_index/hashed_index.hpp:443
#1 find<qpid::framing::SequenceNumber> (this=<value optimized out>, m=<value optimized out>, q=..., remove=false)
at /usr/include/boost/multi_index/hashed_index.hpp:429
#2 qpid::broker::RingQueuePolicy::find (this=<value optimized out>, m=<value optimized out>, q=..., remove=false)
at qpid/broker/QueuePolicy.cpp:330
#3 0x00007f74486e1ecd in qpid::broker::Queue::isEnqueued (this=0x7f742c05d480, msg=...) at qpid/broker/Queue.cpp:1867
#4 0x00007f74486ecef7 in qpid::broker::Queue::dequeue (this=0x7f742c05d480, ctxt=0x0, msg=..., removed=false)
at qpid/broker/Queue.cpp:1089
#5 0x00007f744868f1df in qpid::broker::DeliveryRecord::accept (this=0x7f74380d36b0, ctxt=0x0) at qpid/broker/DeliveryRecord.cpp:120
#6 0x00007f7448731687 in operator() (__first=..., __last=..., __pred=...) at /usr/include/boost/bind/mem_fn_template.hpp:181
#7 operator()<bool, boost::_mfi::mf1<bool, qpid::broker::DeliveryRecord, qpid::broker::TransactionContext*>, boost::_bi::list1<qpid::broker::DeliveryRecord&> > (__first=..., __last=..., __pred=...) at /usr/include/boost/bind/bind.hpp:296
#8 operator()<qpid::broker::DeliveryRecord> (__first=..., __last=..., __pred=...) at /usr/include/boost/bind/bind_template.hpp:32
#9 operator() (__first=..., __last=..., __pred=...) at qpid/broker/SemanticState.cpp:786
#10 std::__find_if<std::_Deque_iterator<qpid::broker::DeliveryRecord, qpid::broker::DeliveryRecord&, qpid::broker::DeliveryRecord*>, qpid::broker::IsInSequenceSetAnd<boost::_bi::bind_t<bool, boost::_mfi::mf1<bool, qpid::broker::DeliveryRecord, qpid::broker::TransactionContext*>, boost::_bi::list2<boost::arg<1>, boost::_bi::value<qpid::broker::TransactionContext*> > > > > (__first=..., __last=...,
__pred=...) at /usr/include/c++/4.4.7/bits/stl_algo.h:222
#11 0x00007f7448731c99 in find_if<std::_Deque_iterator<qpid::broker::DeliveryRecord, qpid::broker::DeliveryRecord&, qpid::broker::DeliveryRecord*>, qpid::broker::IsInSequenceSetAnd<boost::_bi::bind_t<bool, boost::_mfi::mf1<bool, qpid::broker::DeliveryRecord, qpid::broker::TransactionContext*>, boost::_bi::list2<boost::arg<1>, boost::_bi::value<qpid::broker::TransactionContext*> > > > > (__first=...,
__last=..., __pred=...) at /usr/include/c++/4.4.7/bits/stl_algo.h:4248
#12 std::remove_if<std::_Deque_iterator<qpid::broker::DeliveryRecord, qpid::broker::DeliveryRecord&, qpid::broker::DeliveryRecord*>, qpid::broker::IsInSequenceSetAnd<boost::_bi::bind_t<bool, boost::_mfi::mf1<bool, qpid::broker::DeliveryRecord, qpid::broker::TransactionContext*>, boost::_bi::list2<boost::arg<1>, boost::_bi::value<qpid::broker::TransactionContext*> > > > > (__first=..., __last=...,
__pred=...) at /usr/include/c++/4.4.7/bits/stl_algo.h:1153
#13 0x00007f744872981d in qpid::broker::SemanticState::accepted (this=0x7f7434005f38, commands=...)
at qpid/broker/SemanticState.cpp:823
#14 0x00007f74481ad4d3 in invoke<qpid::framing::AMQP_ServerOperations::MessageHandler> (this=<value optimized out>,
body=<value optimized out>) at qpid/framing/MessageAcceptBody.h:64
..
Fixed http://git.app.eng.bos.redhat.com/git/rh-qpid.git/commit/?h=0.18-mrg-aconway-bz1121615 Treat priorities > 9 as priority 9. Confirmed that this is not a problem on 0.22-mrg or trunk. Rebased to include: 0632fb6 Bug 860691,QPID-4287: Poor performance when a priority queue with a ring queue policy has a large backlog New branch: http://git.app.eng.bos.redhat.com/git/rh-qpid.git/log/?h=0.18-mrg-aconway-bz1121615-2 Stress-tested 0.18-27 by sending & consuming messages with various (wrong) priority, no issue found. No impact to performance (wrt. orig bz 860691). This issue is fixed. Verified OS: RHEL 6 x86_64, i386; RHEL 5 x86_64, i386 Packages: qpid-cpp-client-devel-docs-0.18-25.el6 qpid-cpp-client-devel-0.18-32.el6 qpid-cpp-client-ssl-0.18-32.el6 qpid-cpp-client-0.18-32.el6 qpid-cpp-debuginfo-0.18-32.el6 qpid-cpp-server-devel-0.18-32.el6 qpid-cpp-server-ssl-0.18-32.el6 qpid-cpp-server-store-0.18-32.el6 qpid-cpp-server-xml-0.18-32.el6 qpid-cpp-server-0.18-32.el6 qpid-tools-0.18-10.el6_4 -> VERIFIED Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://rhn.redhat.com/errata/RHBA-2014-1682.html |