Segfault in new ConnectionManager

When creating a stream with a protocol that fails to setup the stream, this
code segfaults in the find_if statement:

138             void ConnectionManager::removeConnection(ConnID* conn_id)
139             {
140                 ChannelDescriptor descriptor;
141                 { RTT::os::MutexLock lock(connection_lock);
142                     std::list<ChannelDescriptor>::iterator conn_it =
143                         std::find_if(connections.begin(), 
connections.end(), boost::bind(&ConnectionManager::findMatchingPort, this, 
conn_id, _1));
144                     if (conn_it == connections.end()) return;
145                     descriptor = *conn_it;
146                     connections.erase(conn_it);
147                 }

To reproduce, fire up the deployer, make sure mqueues are enabled and type for
a component that has an InputPort<double>:
var ConnPolicy cp
cp.transport = 2
createStream("component", "port", cp)

The backtrace is: (not always a null pointer address on the stack)

#0 0x00000000000000a0 in ?? ()
#1 0x00007ffff7f5d341 in operator() (this=0x7fffffffd698, conn_id=<value optimized
out>) at /usr/include/boost/bind/mem_fn_template.hpp:274
#2 operator()<bool, boost::_mfi::mf2 const RTT::internal::ConnID*, const
boost::tuples::tuple boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type>&>,
boost::_bi::list1<boost::tuples::tuple boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type>&> > (this=0x7fffffffd698, conn_id=<value optimized
out>) at /usr/include/boost/bind/bind.hpp:375
#3 operator()<boost::tuples::tuple boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type> > (this=0x7fffffffd698, conn_id=<value optimized out>)
at /usr/include/boost/bind/bind_template.hpp:32
#4
__find_if<std::_List_iterator boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type> >, boost::_bi::bind_t<bool, boost::_mfi::mf2 RTT::internal::ConnectionManager, RTT::internal::ConnID const*,
boost::tuples::tuple boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type> const&>,
boost::_bi::list3<boost::_bi::value boost::_bi::value<RTT::internal::ConnID*>, boost::arg<1> > > > (
this=0x7fffffffd698, conn_id=<value optimized out>) at
/usr/include/c++/4.4/bits/stl_algo.h:158
#5
find_if<std::_List_iterator boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type> >, boost::_bi::bind_t<bool, boost::_mfi::mf2 RTT::internal::ConnectionManager, RTT::internal::ConnID const*,
boost::tuples::tuple boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type> const&>,
boost::_bi::list3<boost::_bi::value boost::_bi::value<RTT::internal::ConnID*>, boost::arg<1> > > > (
this=0x7fffffffd698, conn_id=<value optimized out>) at
/usr/include/c++/4.4/bits/stl_algo.h:4248
#6 RTT::internal::ConnectionManager::removeConnection (this=0x7fffffffd698,
conn_id=<value optimized out>) at /home/kaltan/src/git/orocos-
toolchain/rtt/rtt/internal/ConnectionManager.cpp:143
#7 0x000000000042f5de in createStream<double> (this=0x7fffffffd678,
policy=<value optimized out>) at /home/kaltan/src/git/orocos-
toolchain/rtt/install/include/rtt/internal/ConnFactory.hpp:319
#8 RTT::InputPort<double>::createStream (this=0x7fffffffd678, policy=<value
optimized out>) at /home/kaltan/src/git/orocos-
toolchain/rtt/install/include/rtt/InputPort.hpp:150

Couldn't find out immediately what went wrong in createStream.

Peter

Segfault in new ConnectionManager

On 11/22/2010 03:56 PM, Peter Soetens wrote:
> When creating a stream with a protocol that fails to setup the stream, this
> code segfaults in the find_if statement:
>
>

> 138             void ConnectionManager::removeConnection(ConnID* conn_id)
> 139             {
> 140                 ChannelDescriptor descriptor;
> 141                 { RTT::os::MutexLock lock(connection_lock);
> 142                     std::list<ChannelDescriptor>::iterator conn_it =
> 143                         std::find_if(connections.begin(),
> connections.end(), boost::bind(&ConnectionManager::findMatchingPort, this,
> conn_id, _1));
> 144                     if (conn_it == connections.end()) return;
> 145                     descriptor = *conn_it;
> 146                     connections.erase(conn_it);
> 147                 }
> 

Apart from the fact that it should not crash ...
* you don't need to call removeConnection as the connection has never
been added (createAndCheckStream returns false only if the
connection has not been added)
* it seems to me that the connection ID created in
RTT::InputPort<T>::createStream is being leaked

Segfault in new ConnectionManager

On 11/22/2010 03:56 PM, Peter Soetens wrote:
> When creating a stream with a protocol that fails to setup the stream, this
> code segfaults in the find_if statement:
>
>

> 138             void ConnectionManager::removeConnection(ConnID* conn_id)
> 139             {
> 140                 ChannelDescriptor descriptor;
> 141                 { RTT::os::MutexLock lock(connection_lock);
> 142                     std::list<ChannelDescriptor>::iterator conn_it =
> 143                         std::find_if(connections.begin(),
> connections.end(), boost::bind(&ConnectionManager::findMatchingPort, this,
> conn_id, _1));
> 144                     if (conn_it == connections.end()) return;
> 145                     descriptor = *conn_it;
> 146                     connections.erase(conn_it);
> 147                 }
> 

>
>
> To reproduce, fire up the deployer, make sure mqueues are enabled and type for
> a component that has an InputPort<double>:
> var ConnPolicy cp
> cp.transport = 2
> createStream("component", "port", cp)
>
> The backtrace is: (not always a null pointer address on the stack)
>
> #0 0x00000000000000a0 in ?? ()
> #1 0x00007ffff7f5d341 in operator() (this=0x7fffffffd698, conn_id=<value optimized
> out>) at /usr/include/boost/bind/mem_fn_template.hpp:274
> #2 operator()<bool, boost::_mfi::mf2 > const RTT::internal::ConnID*, const
> boost::tuples::tuple<boost::shared_ptr > boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type>&>,
> boost::_bi::list1<boost::tuples::tuple > boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type>&> > (this=0x7fffffffd698, conn_id=<value optimized
> out>) at /usr/include/boost/bind/bind.hpp:375
> #3 operator()<boost::tuples::tuple > boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type> > (this=0x7fffffffd698, conn_id=<value optimized out>)
> at /usr/include/boost/bind/bind_template.hpp:32
> #4
> __find_if<std::_List_iterator > boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type> >, boost::_bi::bind_t<bool, boost::_mfi::mf2 > RTT::internal::ConnectionManager, RTT::internal::ConnID const*,
> boost::tuples::tuple<boost::shared_ptr > boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type> const&>,
> boost::_bi::list3<boost::_bi::value > boost::_bi::value<RTT::internal::ConnID*>, boost::arg<1> > > > (
> this=0x7fffffffd698, conn_id=<value optimized out>) at
> /usr/include/c++/4.4/bits/stl_algo.h:158
> #5
> find_if<std::_List_iterator > boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type> >, boost::_bi::bind_t<bool, boost::_mfi::mf2 > RTT::internal::ConnectionManager, RTT::internal::ConnID const*,
> boost::tuples::tuple<boost::shared_ptr > boost::intrusive_ptr<RTT::base::ChannelElementBase>, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type> const&>,
> boost::_bi::list3<boost::_bi::value > boost::_bi::value<RTT::internal::ConnID*>, boost::arg<1> > > > (
> this=0x7fffffffd698, conn_id=<value optimized out>) at
> /usr/include/c++/4.4/bits/stl_algo.h:4248
> #6 RTT::internal::ConnectionManager::removeConnection (this=0x7fffffffd698,
> conn_id=<value optimized out>) at /home/kaltan/src/git/orocos-
> toolchain/rtt/rtt/internal/ConnectionManager.cpp:143
> #7 0x000000000042f5de in createStream<double> (this=0x7fffffffd678,
> policy=<value optimized out>) at /home/kaltan/src/git/orocos-
> toolchain/rtt/install/include/rtt/internal/ConnFactory.hpp:319
> #8 RTT::InputPort<double>::createStream (this=0x7fffffffd678, policy=<value
> optimized out>) at /home/kaltan/src/git/orocos-
> toolchain/rtt/install/include/rtt/InputPort.hpp:150
>
> Couldn't find out immediately what went wrong in createStream.

Could you run that with valgrind ?

Segfault in new ConnectionManager

On Monday 22 November 2010 17:12:54 Sylvain Joyeux wrote:
> On 11/22/2010 03:56 PM, Peter Soetens wrote:
> > When creating a stream with a protocol that fails to setup the stream,
> > this code segfaults in the find_if statement:
> >
> >

> > 138             void ConnectionManager::removeConnection(ConnID* conn_id)
> > 139             {
> > 140                 ChannelDescriptor descriptor;
> > 141                 { RTT::os::MutexLock lock(connection_lock);
> > 142                     std::list<ChannelDescriptor>::iterator conn_it =
> > 143                         std::find_if(connections.begin(),
> > connections.end(), boost::bind(&ConnectionManager::findMatchingPort,
> > this, conn_id, _1));
> > 144                     if (conn_it == connections.end()) return;
> > 145                     descriptor = *conn_it;
> > 146                     connections.erase(conn_it);
> > 147                 }
> > 

> >
> >
> > To reproduce, fire up the deployer, make sure mqueues are enabled and
> > type for a component that has an InputPort<double>:
> > var ConnPolicy cp
> > cp.transport = 2
> > createStream("component", "port", cp)
> >
> > The backtrace is: (not always a null pointer address on the stack)
> >
> > #0 0x00000000000000a0 in ?? ()
> > #1 0x00007ffff7f5d341 in operator() (this=0x7fffffffd698, conn_id=<value
> > optimized out>) at /usr/include/boost/bind/mem_fn_template.hpp:274
> > #2 operator()<bool, boost::_mfi::mf2 > > RTT::internal::ConnectionManager, const RTT::internal::ConnID*, const
> > boost::tuples::tuple<boost::shared_ptr > > boost::intrusive_ptr<RTT::base::ChannelElementBase>,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type>&>,
> > boost::_bi::list1<boost::tuples::tuple > > onnID>, boost::intrusive_ptr<RTT::base::ChannelElementBase>,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type>&> >
> > (this=0x7fffffffd698, conn_id=<value optimized out>) at
> > /usr/include/boost/bind/bind.hpp:375
> > #3
> > operator()<boost::tuples::tuple > > , boost::intrusive_ptr<RTT::base::ChannelElementBase>,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type> >
> > (this=0x7fffffffd698, conn_id=<value optimized out>) at
> > /usr/include/boost/bind/bind_template.hpp:32
> > #4
> > __find_if<std::_List_iterator > > :internal::ConnID>, boost::intrusive_ptr<RTT::base::ChannelElementBase>,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type> >,
> > boost::_bi::bind_t<bool, boost::_mfi::mf2 > > RTT::internal::ConnectionManager, RTT::internal::ConnID const*,
> > boost::tuples::tuple<boost::shared_ptr > > boost::intrusive_ptr<RTT::base::ChannelElementBase>,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type> const&>,
> > boost::_bi::list3<boost::_bi::value > > boost::_bi::value<RTT::internal::ConnID*>, boost::arg<1> > > > (
> >
> > this=0x7fffffffd698, conn_id=<value optimized out>) at
> >
> > /usr/include/c++/4.4/bits/stl_algo.h:158
> > #5
> > find_if<std::_List_iterator > > nternal::ConnID>, boost::intrusive_ptr<RTT::base::ChannelElementBase>,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type> >,
> > boost::_bi::bind_t<bool, boost::_mfi::mf2 > > RTT::internal::ConnectionManager, RTT::internal::ConnID const*,
> > boost::tuples::tuple<boost::shared_ptr > > boost::intrusive_ptr<RTT::base::ChannelElementBase>,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type,
> > boost::tuples::null_type, boost::tuples::null_type> const&>,
> > boost::_bi::list3<boost::_bi::value > > boost::_bi::value<RTT::internal::ConnID*>, boost::arg<1> > > > (
> >
> > this=0x7fffffffd698, conn_id=<value optimized out>) at
> >
> > /usr/include/c++/4.4/bits/stl_algo.h:4248
> > #6 RTT::internal::ConnectionManager::removeConnection
> > (this=0x7fffffffd698, conn_id=<value optimized out>) at
> > /home/kaltan/src/git/orocos-
> > toolchain/rtt/rtt/internal/ConnectionManager.cpp:143
> > #7 0x000000000042f5de in createStream<double> (this=0x7fffffffd678,
> > policy=<value optimized out>) at /home/kaltan/src/git/orocos-
> > toolchain/rtt/install/include/rtt/internal/ConnFactory.hpp:319
> > #8 RTT::InputPort<double>::createStream (this=0x7fffffffd678,
> > policy=<value optimized out>) at /home/kaltan/src/git/orocos-
> > toolchain/rtt/install/include/rtt/InputPort.hpp:150
> >
> > Couldn't find out immediately what went wrong in createStream.
>
> Could you run that with valgrind ?

Stupid me, should have done this in the first place:

Deployer [S]> createStream ("ComponentA","p1",cp)
47.363 [ Debug ][MQSendRecv] Opened '/ComponentA.p1.0x9879390@5818' with mqdes='4' for reading.
47.882 [ ERROR ][../../../bin/deploy::main()] Failed to receive initial data sample for MQ Channel Element.
47.898 [ ERROR ][../../../bin/deploy::main()] Failed to create input stream for input port p1
==5818== Invalid read of size 8
==5818== at 0x415A5BB: RTT::internal::ConnectionManager::findMatchingPort(RTT::internal::ConnID const*,
boost::tuples::tuple<boost::shared_ptr boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> const&) (ConnectionManager.cpp:86)
==5818== by 0x415B340: RTT::internal::ConnectionManager::removeConnection(RTT::internal::ConnID*) (mem_fn_template.hpp:274)
==5818== by 0x42F5DD: RTT::InputPort<double>::createStream(RTT::ConnPolicy const&) (ConnFactory.hpp:319)
==5818== by 0x4F3A932: OCL::DeploymentComponent::createStream(std::string const&, std::string const&, RTT::ConnPolicy)
(DeploymentComponent.cpp:401)
==5818== by 0x4F8AB2F: boost::detail::function::function_obj_invoker3<boost::_bi::bind_t boost::_mfi::mf3 boost::_bi::list4<boost::_bi::value const&, std::string const&, RTT::ConnPolicy>::invoke(boost::detail::function::function_buffer&, std::string const&, std::string const&,
RTT::ConnPolicy) (mem_fn_template.hpp:384)
==5818== by 0x4FAC7DF: bool RTT::internal::LocalOperationCallerImpl<bool ()(std::string const&, std::string const&,
RTT::ConnPolicy)>::call_impl<std::string const&, std::string const&, RTT::ConnPolicy>(std::string const&, std::string const&, RTT::ConnPolicy)
(function_template.hpp:1013)
==5818== by 0x4FAC993: RTT::internal::InvokerImpl<3, bool ()(std::string const&, std::string const&, RTT::ConnPolicy),
RTT::internal::LocalOperationCallerImpl<bool ()(std::string const&, std::string const&, RTT::ConnPolicy)> >::call(std::string const&,
std::string const&, RTT::ConnPolicy) (Invoker.hpp:158)
==5818== by 0x4F8B813: boost::fusion::result_of::invoke<bool (RTT::base::OperationCallerBase const&, RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy),
boost::fusion::cons<RTT::base::OperationCallerBase boost::fusion::cons<std::string const&, boost::fusion::cons > const>::type boost::fusion::invoke<bool (RTT::base::OperationCallerBase RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy), boost::fusion::cons<RTT::base::OperationCallerBase (std::string const&, std::string const&, RTT::ConnPolicy)>*, boost::fusion::cons<std::string const&, boost::fusion::cons boost::fusion::cons const&, RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy),
boost::fusion::cons<RTT::base::OperationCallerBase boost::fusion::cons<std::string const&, boost::fusion::cons > const&) (invoke.hpp:279)
==5818== by 0x4F98D9E: RTT::internal::FusedMCallDataSource<bool ()(std::string const&, std::string const&,
RTT::ConnPolicy)>::evaluate() const (bind.hpp:296)
==5818== by 0x4E4173E: OCL::TaskBrowser::doPrint(boost::intrusive_ptr<RTT::base::DataSourceBase>, bool) (TaskBrowser.cpp:1484)
==5818== by 0x4E4213C: OCL::TaskBrowser::printResult(RTT::base::DataSourceBase*, bool) (TaskBrowser.cpp:1445)
==5818== by 0x4E43742: OCL::TaskBrowser::evalCommand(std::string&) (TaskBrowser.cpp:1361)
==5818== Address 0x9879250 is 0 bytes inside a block of size 16 free'd
==5818== at 0x4C26DCF: operator delete(void*) (vg_replace_malloc.c:387)
==5818== by 0x416D7DC: RTT::internal::StreamConnID::~StreamConnID() (ConnFactory.hpp:76)
==5818== by 0x415B4DF: RTT::internal::ConnectionManager::removeConnection(RTT::internal::ConnID*)
(sp_counted_base_gcc_x86.hpp:145)
==5818== by 0x414CD1F: RTT::base::InputPortInterface::channelReady(boost::intrusive_ptr<RTT::base::ChannelElementBase>)
(InputPortInterface.cpp:107)
==5818== by 0x416D0AE: RTT::internal::ConnFactory::createAndCheckStream(RTT::base::InputPortInterface&, RTT::ConnPolicy const&,
boost::intrusive_ptr<RTT::base::ChannelElementBase>, RTT::internal::StreamConnID*) (ConnFactory.cpp:187)
==5818== by 0x42F5B3: RTT::InputPort<double>::createStream(RTT::ConnPolicy const&) (ConnFactory.hpp:317)
==5818== by 0x4F3A932: OCL::DeploymentComponent::createStream(std::string const&, std::string const&, RTT::ConnPolicy)
(DeploymentComponent.cpp:401)
==5818== by 0x4F8AB2F: boost::detail::function::function_obj_invoker3<boost::_bi::bind_t boost::_mfi::mf3 boost::_bi::list4<boost::_bi::value const&, std::string const&, RTT::ConnPolicy>::invoke(boost::detail::function::function_buffer&, std::string const&, std::string const&,
RTT::ConnPolicy) (mem_fn_template.hpp:384)
==5818== by 0x4FAC7DF: bool RTT::internal::LocalOperationCallerImpl<bool ()(std::string const&, std::string const&,
RTT::ConnPolicy)>::call_impl<std::string const&, std::string const&, RTT::ConnPolicy>(std::string const&, std::string const&, RTT::ConnPolicy)
(function_template.hpp:1013)
==5818== by 0x4FAC993: RTT::internal::InvokerImpl<3, bool ()(std::string const&, std::string const&, RTT::ConnPolicy),
RTT::internal::LocalOperationCallerImpl<bool ()(std::string const&, std::string const&, RTT::ConnPolicy)> >::call(std::string const&,
std::string const&, RTT::ConnPolicy) (Invoker.hpp:158)
==5818== by 0x4F8B813: boost::fusion::result_of::invoke<bool (RTT::base::OperationCallerBase const&, RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy),
boost::fusion::cons<RTT::base::OperationCallerBase boost::fusion::cons<std::string const&, boost::fusion::cons > const>::type boost::fusion::invoke<bool (RTT::base::OperationCallerBase RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy), boost::fusion::cons<RTT::base::OperationCallerBase (std::string const&, std::string const&, RTT::ConnPolicy)>*, boost::fusion::cons<std::string const&, boost::fusion::cons boost::fusion::cons const&, RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy),
boost::fusion::cons<RTT::base::OperationCallerBase boost::fusion::cons<std::string const&, boost::fusion::cons > const&) (invoke.hpp:279)
==5818== by 0x4F98D9E: RTT::internal::FusedMCallDataSource<bool ()(std::string const&, std::string const&,
RTT::ConnPolicy)>::evaluate() const (bind.hpp:296)
==5818==
pure virtual method called
terminate called without an active exception

It's accessing a free'd connection id. channelReady() had already called removeConnection, which deleted the id object.

Peter

Segfault in new ConnectionManager

On 11/22/2010 09:58 PM, Peter Soetens wrote:
> On Monday 22 November 2010 17:12:54 Sylvain Joyeux wrote:
>> On 11/22/2010 03:56 PM, Peter Soetens wrote:
>>> When creating a stream with a protocol that fails to setup the stream,
>>> this code segfaults in the find_if statement:
>>>
>>>

>>> 138             void ConnectionManager::removeConnection(ConnID* conn_id)
>>> 139             {
>>> 140                 ChannelDescriptor descriptor;
>>> 141                 { RTT::os::MutexLock lock(connection_lock);
>>> 142                     std::list<ChannelDescriptor>::iterator conn_it =
>>> 143                         std::find_if(connections.begin(),
>>> connections.end(), boost::bind(&ConnectionManager::findMatchingPort,
>>> this, conn_id, _1));
>>> 144                     if (conn_it == connections.end()) return;
>>> 145                     descriptor = *conn_it;
>>> 146                     connections.erase(conn_it);
>>> 147                 }
>>> 

>>>
>>>
>>> To reproduce, fire up the deployer, make sure mqueues are enabled and
>>> type for a component that has an InputPort<double>:
>>> var ConnPolicy cp
>>> cp.transport = 2
>>> createStream("component", "port", cp)
>>>
>>> The backtrace is: (not always a null pointer address on the stack)
>>>
>>> #0 0x00000000000000a0 in ?? ()
>>> #1 0x00007ffff7f5d341 in operator() (this=0x7fffffffd698, conn_id=<value
>>> optimized out>) at /usr/include/boost/bind/mem_fn_template.hpp:274
>>> #2 operator()<bool, boost::_mfi::mf2 >>> RTT::internal::ConnectionManager, const RTT::internal::ConnID*, const
>>> boost::tuples::tuple<boost::shared_ptr >>> boost::intrusive_ptr<RTT::base::ChannelElementBase>,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type>&>,
>>> boost::_bi::list1<boost::tuples::tuple >>> onnID>, boost::intrusive_ptr<RTT::base::ChannelElementBase>,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type>&> >
>>> (this=0x7fffffffd698, conn_id=<value optimized out>) at
>>> /usr/include/boost/bind/bind.hpp:375
>>> #3
>>> operator()<boost::tuples::tuple >>> , boost::intrusive_ptr<RTT::base::ChannelElementBase>,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type> >
>>> (this=0x7fffffffd698, conn_id=<value optimized out>) at
>>> /usr/include/boost/bind/bind_template.hpp:32
>>> #4
>>> __find_if<std::_List_iterator >>> :internal::ConnID>, boost::intrusive_ptr<RTT::base::ChannelElementBase>,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type> >,
>>> boost::_bi::bind_t<bool, boost::_mfi::mf2 >>> RTT::internal::ConnectionManager, RTT::internal::ConnID const*,
>>> boost::tuples::tuple<boost::shared_ptr >>> boost::intrusive_ptr<RTT::base::ChannelElementBase>,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type> const&>,
>>> boost::_bi::list3<boost::_bi::value >>> boost::_bi::value<RTT::internal::ConnID*>, boost::arg<1> > > > (
>>>
>>> this=0x7fffffffd698, conn_id=<value optimized out>) at
>>>
>>> /usr/include/c++/4.4/bits/stl_algo.h:158
>>> #5
>>> find_if<std::_List_iterator >>> nternal::ConnID>, boost::intrusive_ptr<RTT::base::ChannelElementBase>,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type> >,
>>> boost::_bi::bind_t<bool, boost::_mfi::mf2 >>> RTT::internal::ConnectionManager, RTT::internal::ConnID const*,
>>> boost::tuples::tuple<boost::shared_ptr >>> boost::intrusive_ptr<RTT::base::ChannelElementBase>,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type,
>>> boost::tuples::null_type, boost::tuples::null_type> const&>,
>>> boost::_bi::list3<boost::_bi::value >>> boost::_bi::value<RTT::internal::ConnID*>, boost::arg<1> > > > (
>>>
>>> this=0x7fffffffd698, conn_id=<value optimized out>) at
>>>
>>> /usr/include/c++/4.4/bits/stl_algo.h:4248
>>> #6 RTT::internal::ConnectionManager::removeConnection
>>> (this=0x7fffffffd698, conn_id=<value optimized out>) at
>>> /home/kaltan/src/git/orocos-
>>> toolchain/rtt/rtt/internal/ConnectionManager.cpp:143
>>> #7 0x000000000042f5de in createStream<double> (this=0x7fffffffd678,
>>> policy=<value optimized out>) at /home/kaltan/src/git/orocos-
>>> toolchain/rtt/install/include/rtt/internal/ConnFactory.hpp:319
>>> #8 RTT::InputPort<double>::createStream (this=0x7fffffffd678,
>>> policy=<value optimized out>) at /home/kaltan/src/git/orocos-
>>> toolchain/rtt/install/include/rtt/InputPort.hpp:150
>>>
>>> Couldn't find out immediately what went wrong in createStream.
>>
>> Could you run that with valgrind ?
>
> Stupid me, should have done this in the first place:
>
> Deployer [S]> createStream ("ComponentA","p1",cp)
> 47.363 [ Debug ][MQSendRecv] Opened '/ComponentA.p1.0x9879390@5818' with mqdes='4' for reading.
> 47.882 [ ERROR ][../../../bin/deploy::main()] Failed to receive initial data sample for MQ Channel Element.
> 47.898 [ ERROR ][../../../bin/deploy::main()] Failed to create input stream for input port p1
> ==5818== Invalid read of size 8
> ==5818== at 0x415A5BB: RTT::internal::ConnectionManager::findMatchingPort(RTT::internal::ConnID const*,
> boost::tuples::tuple<boost::shared_ptr > boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
> boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> const&) (ConnectionManager.cpp:86)
> ==5818== by 0x415B340: RTT::internal::ConnectionManager::removeConnection(RTT::internal::ConnID*) (mem_fn_template.hpp:274)
> ==5818== by 0x42F5DD: RTT::InputPort<double>::createStream(RTT::ConnPolicy const&) (ConnFactory.hpp:319)
> ==5818== by 0x4F3A932: OCL::DeploymentComponent::createStream(std::string const&, std::string const&, RTT::ConnPolicy)
> (DeploymentComponent.cpp:401)
> ==5818== by 0x4F8AB2F: boost::detail::function::function_obj_invoker3<boost::_bi::bind_t > boost::_mfi::mf3<bool, OCL::DeploymentComponent, std::string const&, std::string const&, RTT::ConnPolicy>,
> boost::_bi::list4<boost::_bi::value > const&, std::string const&, RTT::ConnPolicy>::invoke(boost::detail::function::function_buffer&, std::string const&, std::string const&,
> RTT::ConnPolicy) (mem_fn_template.hpp:384)
> ==5818== by 0x4FAC7DF: bool RTT::internal::LocalOperationCallerImpl<bool ()(std::string const&, std::string const&,
> RTT::ConnPolicy)>::call_impl<std::string const&, std::string const&, RTT::ConnPolicy>(std::string const&, std::string const&, RTT::ConnPolicy)
> (function_template.hpp:1013)
> ==5818== by 0x4FAC993: RTT::internal::InvokerImpl<3, bool ()(std::string const&, std::string const&, RTT::ConnPolicy),
> RTT::internal::LocalOperationCallerImpl<bool ()(std::string const&, std::string const&, RTT::ConnPolicy)> >::call(std::string const&,
> std::string const&, RTT::ConnPolicy) (Invoker.hpp:158)
> ==5818== by 0x4F8B813: boost::fusion::result_of::invoke<bool (RTT::base::OperationCallerBase > const&, RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy),
> boost::fusion::cons<RTT::base::OperationCallerBase > boost::fusion::cons<std::string const&, boost::fusion::cons >> const>::type boost::fusion::invoke<bool (RTT::base::OperationCallerBase > RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy), boost::fusion::cons<RTT::base::OperationCallerBase > (std::string const&, std::string const&, RTT::ConnPolicy)>*, boost::fusion::cons<std::string const&, boost::fusion::cons > boost::fusion::cons<RTT::ConnPolicy, boost::fusion::nil> > > > >(bool (RTT::base::OperationCallerBase<bool ()(std::string const&, std::string
> const&, RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy),
> boost::fusion::cons<RTT::base::OperationCallerBase > boost::fusion::cons<std::string const&, boost::fusion::cons >> const&) (invoke.hpp:279)
> ==5818== by 0x4F98D9E: RTT::internal::FusedMCallDataSource<bool ()(std::string const&, std::string const&,
> RTT::ConnPolicy)>::evaluate() const (bind.hpp:296)
> ==5818== by 0x4E4173E: OCL::TaskBrowser::doPrint(boost::intrusive_ptr<RTT::base::DataSourceBase>, bool) (TaskBrowser.cpp:1484)
> ==5818== by 0x4E4213C: OCL::TaskBrowser::printResult(RTT::base::DataSourceBase*, bool) (TaskBrowser.cpp:1445)
> ==5818== by 0x4E43742: OCL::TaskBrowser::evalCommand(std::string&) (TaskBrowser.cpp:1361)
> ==5818== Address 0x9879250 is 0 bytes inside a block of size 16 free'd
> ==5818== at 0x4C26DCF: operator delete(void*) (vg_replace_malloc.c:387)
> ==5818== by 0x416D7DC: RTT::internal::StreamConnID::~StreamConnID() (ConnFactory.hpp:76)
> ==5818== by 0x415B4DF: RTT::internal::ConnectionManager::removeConnection(RTT::internal::ConnID*)
> (sp_counted_base_gcc_x86.hpp:145)
> ==5818== by 0x414CD1F: RTT::base::InputPortInterface::channelReady(boost::intrusive_ptr<RTT::base::ChannelElementBase>)
> (InputPortInterface.cpp:107)
> ==5818== by 0x416D0AE: RTT::internal::ConnFactory::createAndCheckStream(RTT::base::InputPortInterface&, RTT::ConnPolicy const&,
> boost::intrusive_ptr<RTT::base::ChannelElementBase>, RTT::internal::StreamConnID*) (ConnFactory.cpp:187)
> ==5818== by 0x42F5B3: RTT::InputPort<double>::createStream(RTT::ConnPolicy const&) (ConnFactory.hpp:317)
> ==5818== by 0x4F3A932: OCL::DeploymentComponent::createStream(std::string const&, std::string const&, RTT::ConnPolicy)
> (DeploymentComponent.cpp:401)
> ==5818== by 0x4F8AB2F: boost::detail::function::function_obj_invoker3<boost::_bi::bind_t > boost::_mfi::mf3<bool, OCL::DeploymentComponent, std::string const&, std::string const&, RTT::ConnPolicy>,
> boost::_bi::list4<boost::_bi::value > const&, std::string const&, RTT::ConnPolicy>::invoke(boost::detail::function::function_buffer&, std::string const&, std::string const&,
> RTT::ConnPolicy) (mem_fn_template.hpp:384)
> ==5818== by 0x4FAC7DF: bool RTT::internal::LocalOperationCallerImpl<bool ()(std::string const&, std::string const&,
> RTT::ConnPolicy)>::call_impl<std::string const&, std::string const&, RTT::ConnPolicy>(std::string const&, std::string const&, RTT::ConnPolicy)
> (function_template.hpp:1013)
> ==5818== by 0x4FAC993: RTT::internal::InvokerImpl<3, bool ()(std::string const&, std::string const&, RTT::ConnPolicy),
> RTT::internal::LocalOperationCallerImpl<bool ()(std::string const&, std::string const&, RTT::ConnPolicy)> >::call(std::string const&,
> std::string const&, RTT::ConnPolicy) (Invoker.hpp:158)
> ==5818== by 0x4F8B813: boost::fusion::result_of::invoke<bool (RTT::base::OperationCallerBase > const&, RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy),
> boost::fusion::cons<RTT::base::OperationCallerBase > boost::fusion::cons<std::string const&, boost::fusion::cons >> const>::type boost::fusion::invoke<bool (RTT::base::OperationCallerBase > RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy), boost::fusion::cons<RTT::base::OperationCallerBase > (std::string const&, std::string const&, RTT::ConnPolicy)>*, boost::fusion::cons<std::string const&, boost::fusion::cons > boost::fusion::cons<RTT::ConnPolicy, boost::fusion::nil> > > > >(bool (RTT::base::OperationCallerBase<bool ()(std::string const&, std::string
> const&, RTT::ConnPolicy)>::*)(std::string const&, std::string const&, RTT::ConnPolicy),
> boost::fusion::cons<RTT::base::OperationCallerBase > boost::fusion::cons<std::string const&, boost::fusion::cons >> const&) (invoke.hpp:279)
> ==5818== by 0x4F98D9E: RTT::internal::FusedMCallDataSource<bool ()(std::string const&, std::string const&,
> RTT::ConnPolicy)>::evaluate() const (bind.hpp:296)
> ==5818==
> pure virtual method called
> terminate called without an active exception
>
> It's accessing a free'd connection id. channelReady() had already called removeConnection, which deleted the id object.

Yeah. I'm looking at why ...

Sylvain