activemq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Christian Mamen (JIRA)" <j...@apache.org>
Subject [jira] [Comment Edited] (AMQCPP-527) ConcurrentStlMap - stl map find crash with empty map
Date Thu, 12 Dec 2013 20:03:07 GMT

    [ https://issues.apache.org/jira/browse/AMQCPP-527?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13846394#comment-13846394
] 

Christian Mamen edited comment on AMQCPP-527 at 12/12/13 8:01 PM:
------------------------------------------------------------------

[~tabish121] - Is it possible that the ActivemqConnection config->ActiveMQTempDestination
needs synchronization during close()

{code}
void ActiveMQConnection::close() {
   [...]

    // As TemporaryQueue and TemporaryTopic instances are bound to a connection
    // we should just delete them after the connection is closed to free up memory
    ArrayList<Pointer<ActiveMQTempDestination> > tempDests(this->config->activeTempDestinations.values());
    Pointer<Iterator<Pointer<ActiveMQTempDestination> > > iterator(tempDests.iterator());

    try {
        while (iterator->hasNext()) {
            Pointer<ActiveMQTempDestination> dest = iterator->next();
            dest->close();
        }
    } catch (cms::CMSException& error) {
        if (!hasException) {
            ex = ActiveMQException(error.clone());
            hasException = true;
        }
    }
{code}

could become :
{code}
void ActiveMQConnection::close() {
    [...]
        
    try {
        this->config->activeTempDestinations.lock();
        
        // As TemporaryQueue and TemporaryTopic instances are bound to a connection
        // we should just delete them after the connection is closed to free up memory
        ArrayList<Pointer<ActiveMQTempDestination> > tempDests(this->config->activeTempDestinations.values());
        Pointer<Iterator<Pointer<ActiveMQTempDestination> > > iterator(tempDests.iterator());
    
        while (iterator->hasNext()) {
            Pointer<ActiveMQTempDestination> dest = iterator->next();
            dest->close();
        }
        
        this->config->activeTempDestinations.unlock();
    } catch (Exception& error) {
        this->config->activeTempDestinations.unlock();
        if (!hasException) {
            ex = ActiveMQException(error.clone());
            hasException = true;
        }
    }
{code}

One scenario that i have in mind is that Pointer<ActiveMQTempDestination> dest = iterator->next();
at some point (due to a race condition), returns null, and throws a decaf::lang::exceptions::NullPointerException

since the try catch in the activemqconnection close() method only catch cms::exception, the
exception is caugth lower

Please Note :
that i have not reproduce this error yet






was (Author: cmamen):
[~tabish121] - Is it possible that the ActivemqConnection config->ActiveMQTempDestination
needs synchronization during close()

{code}
void ActiveMQConnection::close() {
   [...]

    // As TemporaryQueue and TemporaryTopic instances are bound to a connection
    // we should just delete them after the connection is closed to free up memory
    ArrayList<Pointer<ActiveMQTempDestination> > tempDests(this->config->activeTempDestinations.values());
    Pointer<Iterator<Pointer<ActiveMQTempDestination> > > iterator(tempDests.iterator());

    try {
        while (iterator->hasNext()) {
            Pointer<ActiveMQTempDestination> dest = iterator->next();
            dest->close();
        }
    } catch (cms::CMSException& error) {
        if (!hasException) {
            ex = ActiveMQException(error.clone());
            hasException = true;
        }
    }
{code}

could become :
{code}
void ActiveMQConnection::close() {
    [...]
        
    try {
        this->config->activeTempDestinations.lock();
        
        // As TemporaryQueue and TemporaryTopic instances are bound to a connection
        // we should just delete them after the connection is closed to free up memory
        ArrayList<Pointer<ActiveMQTempDestination> > tempDests(this->config->activeTempDestinations.values());
        Pointer<Iterator<Pointer<ActiveMQTempDestination> > > iterator(tempDests.iterator());
    
        while (iterator->hasNext()) {
            Pointer<ActiveMQTempDestination> dest = iterator->next();
            dest->close();
        }
        
        this->config->activeTempDestinations.unlock();
    } catch (Exception& error) {
        this->config->activeTempDestinations.unlock();
        if (!hasException) {
            ex = ActiveMQException(error.clone());
            hasException = true;
        }
    }
{code}

On scenario that i have in mind is that Pointer<ActiveMQTempDestination> dest = iterator->next();
at some point (due to a race condition), returns null, and throws a decaf::lang::exceptions::NullPointerException

since the try catch in the activemqconnection close() method only catch cms::exception, the
exception is caugth lower

Please Note :
that i have not reproduce this error yet





> ConcurrentStlMap - stl map find crash with empty map
> ----------------------------------------------------
>
>                 Key: AMQCPP-527
>                 URL: https://issues.apache.org/jira/browse/AMQCPP-527
>             Project: ActiveMQ C++ Client
>          Issue Type: Bug
>          Components: Decaf
>    Affects Versions: 3.8.1
>            Reporter: Christian Mamen
>            Assignee: Timothy Bish
>             Fix For: 3.8.3, 3.9.0
>
>
> Recently experience a crash while an activemq work thread attempts to remove a temporary
destination from a ConcurrentStlMap. This crash happens inside a std::map::find() when the
map is currently empty. 
> {code}
> virtual V remove(const K& key) {
>             V result = V();
>             synchronized(&mutex) {
>                 typename std::map<K, V, COMPARATOR>::iterator iter = valueMap.find(key);
>                 if (iter == valueMap.end()) {
>                     return result;
>                 }
> [...]
> {code}
> I look arround in forums and found that some people do experience similar problems with
stl map.
> http://social.msdn.microsoft.com/Forums/en-US/9fdd11cd-ab7a-4173-8fcc-ca239b10fd20/weird-crash-in-c-mapsfind-when-compiled-in-release-mode
> http://www.velocityreviews.com/forums/t278300-std-map-find-throws-exception-when-map-is-empty.html
> so it appears that this error might be an stl issue, (perhaps platform related?). The
workaround suggested is the check if the map is empty before performing a find.
> The stack trace i got
> {noformat}
>  	activemq-cpp.dll!std::_Tree<std::_Tmap_traits<decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>,decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>,decaf::lang::PointerComparator<activemq::commands::ActiveMQDestination,decaf::util::concurrent::atomic::AtomicRefCounter>,std::allocator<std::pair<decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
const ,decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
> >,0> >::_Lbound(const decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
& _Keyval={...})  Line 1264 + 0x8 bytes	C++
>  	activemq-cpp.dll!std::_Tree<std::_Tmap_traits<decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>,decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>,decaf::lang::PointerComparator<activemq::commands::ActiveMQDestination,decaf::util::concurrent::atomic::AtomicRefCounter>,std::allocator<std::pair<decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
const ,decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
> >,0> >::lower_bound(const decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
& _Keyval={...})  Line 1004 + 0x10 bytes	C++
>  	activemq-cpp.dll!std::_Tree<std::_Tmap_traits<decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>,decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>,decaf::lang::PointerComparator<activemq::commands::ActiveMQDestination,decaf::util::concurrent::atomic::AtomicRefCounter>,std::allocator<std::pair<decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
const ,decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
> >,0> >::find(const decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
& _Keyval={...})  Line 982	C++
> >	activemq-cpp.dll!decaf::util::concurrent::ConcurrentStlMap<decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>,decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>,decaf::lang::PointerComparator<activemq::commands::ActiveMQDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
>::remove(const decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
& key={...})  Line 920	C++
>  	activemq-cpp.dll!activemq::core::ActiveMQConnection::removeTempDestination(decaf::lang::Pointer<activemq::commands::ActiveMQTempDestination,decaf::util::concurrent::atomic::AtomicRefCounter>
destination={...})  Line 1828 + 0x25 bytes	C++
>  	activemq-cpp.dll!activemq::core::AdvisoryConsumer::processDestinationInfo(decaf::lang::Pointer<activemq::commands::DestinationInfo,decaf::util::concurrent::atomic::AtomicRefCounter>
info={...})  Line 154	C++
>  	activemq-cpp.dll!activemq::core::AdvisoryConsumer::dispatch(const decaf::lang::Pointer<activemq::commands::MessageDispatch,decaf::util::concurrent::atomic::AtomicRefCounter>
& message={...})  Line 135	C++
>  	activemq-cpp.dll!activemq::core::ActiveMQConnection::onCommand(decaf::lang::Pointer<activemq::commands::Command,decaf::util::concurrent::atomic::AtomicRefCounter>
command={...})  Line 1077	C++
>  	activemq-cpp.dll!activemq::transport::TransportFilter::onCommand(decaf::lang::Pointer<activemq::commands::Command,decaf::util::concurrent::atomic::AtomicRefCounter>
command={...})  Line 91 + 0x27 bytes	C++
>  	activemq-cpp.dll!activemq::transport::correlator::ResponseCorrelator::onCommand(decaf::lang::Pointer<activemq::commands::Command,decaf::util::concurrent::atomic::AtomicRefCounter>
command={...})  Line 295	C++
>  	activemq-cpp.dll!activemq::transport::TransportFilter::onCommand(decaf::lang::Pointer<activemq::commands::Command,decaf::util::concurrent::atomic::AtomicRefCounter>
command={...})  Line 91 + 0x27 bytes	C++
>  	activemq-cpp.dll!activemq::wireformat::openwire::OpenWireFormatNegotiator::onCommand(decaf::lang::Pointer<activemq::commands::Command,decaf::util::concurrent::atomic::AtomicRefCounter>
command={...})  Line 145	C++
>  	activemq-cpp.dll!activemq::transport::TransportFilter::onCommand(decaf::lang::Pointer<activemq::commands::Command,decaf::util::concurrent::atomic::AtomicRefCounter>
command={...})  Line 91 + 0x27 bytes	C++
>  	activemq-cpp.dll!activemq::transport::inactivity::InactivityMonitor::onCommand(decaf::lang::Pointer<activemq::commands::Command,decaf::util::concurrent::atomic::AtomicRefCounter>
command={...})  Line 334	C++
>  	activemq-cpp.dll!activemq::transport::TransportFilter::onCommand(decaf::lang::Pointer<activemq::commands::Command,decaf::util::concurrent::atomic::AtomicRefCounter>
command={...})  Line 91 + 0x27 bytes	C++
>  	activemq-cpp.dll!activemq::transport::IOTransport::fire(decaf::lang::Pointer<activemq::commands::Command,decaf::util::concurrent::atomic::AtomicRefCounter>
command={...})  Line 116	C++
>  	activemq-cpp.dll!activemq::transport::IOTransport::run()  Line 275	C++
>  	activemq-cpp.dll!decaf::lang::Thread::run()  Line 143	C++
>  	activemq-cpp.dll!`anonymous namespace'::runCallback(void * arg=0x02d9c3c8)  Line 266
+ 0x11 bytes	C++
>  	activemq-cpp.dll!`anonymous namespace'::threadEntryMethod(void * arg=0x02d9c3c8)  Line
254 + 0x15 bytes	C++
> {noformat}



--
This message was sent by Atlassian JIRA
(v6.1.4#6159)

Mime
View raw message