Skip to content
This repository was archived by the owner on May 31, 2025. It is now read-only.
This repository was archived by the owner on May 31, 2025. It is now read-only.

protect drop_signal_ with drop_mutex_ #1939

@fujitatomoya

Description

@fujitatomoya

Problem Observed

  • stack trace
gsignal
_gnu_cxx::_verbose_terminate_handler()
std::rethrow_exception(std::__exception_ptr::exception_ptr)
std::terminate()
__cxa_throw
void boost::throw_exception<boost::bad_weak_ptr>(boost::bad_weak_ptr const&)
ros::TransportSubscriberLink::onConnectionDropped(boost::shared_ptr<ros::Connection> const&)
boost::signals2::detail::signal_impl<void (boost::shared_ptr<ros::Connection> const&, ros::Connection::DropReason), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (boost::shared_ptr<ros::Connection> const&, ros::Connection::DropReason)>, boost::function<void (boost::signals2::connection const&, boost::shared_ptr<ros::Connection> const&, ros::Connection::DropReason)>, boost::signals2::mutex>::operator()(boost::shared_ptr<ros::Connection> const&, ros::Connection::DropReason)
ros::Connection::drop(ros::Connection::DropReason)
ros::TransportUDSStream::close()
ros::TransportUDSStream::socketUpdate(int)
ros::PollSet::update(int)
ros::PollManager::threadFunc()

Code Analysis

void TransportSubscriberLink::onConnectionDropped(const ConnectionPtr& conn)
{
(void)conn;
ROS_ASSERT(conn == connection_);
PublicationPtr parent = parent_.lock();
if (parent)
{
ROSCPP_CONN_LOG_DEBUG("Connection to subscriber [%s] to topic [%s] dropped", connection_->getRemoteString().c_str(), topic_.c_str());
parent->removeSubscriberLink(shared_from_this());
}
}

there is a possibility that TransportSubscriberLink could be deleted already via Publication::dropAllConnections.

void Publication::dropAllConnections()
{
// Swap our publishers list with a local one so we can only lock for a short period of time, because a
// side effect of our calling drop() on connections can be re-locking the publishers mutex
V_SubscriberLink local_publishers;
{
boost::mutex::scoped_lock lock(subscriber_links_mutex_);
local_publishers.swap(subscriber_links_);
}
for (V_SubscriberLink::iterator i = local_publishers.begin();
i != local_publishers.end(); ++i)
{
(*i)->drop();
}
}

Suggested Fix

  • Protect drop_signal_ with drop_mutex_, so if TransportLink is already deleted, drop_signal_ is also disconnected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions