Open Sunriseyms opened 2 years ago
Reason:
where throw exception_detail?
call TopicManager::instance()->shutdown()
after TopicManager is destroy;the call chain is NodeHandler::~NodeHandler()->NodeHandler::destruct()->ros::shutdown()->TopicManager::instance()->shutdown()
;
when NodeHandle is destroy, it will call NodeHandle destruct(), collection is raw pointer to keep the reference to TopicManager::instance(), this code is first `delete collection, then it will call
ros::shutdown()after, when collection_ is the last reference to
TopicManager::instance()`, it will crash.
void NodeHandle::destruct()
{
delete collection_;
boost::mutex::scoped_lock lock(g_nh_refcount_mutex);
--g_nh_refcount;
if (g_nh_refcount == 0 && g_node_started_by_nh)
{
ros::shutdown();
}
}
Resolution:
removedelete collection_
after ros::shutdown();
I test this code, it is fine; like this:
void NodeHandle::destruct()
{
boost::mutex::scoped_lock lock(g_nh_refcount_mutex);
--g_nh_refcount;
if (g_nh_refcount == 0 && g_node_started_by_nh)
{
ros::shutdown();
}
delete collection_;
}
// NodeHandleBackingCollection* collection_;
boost::shared_ptr<NodeHandleBackingCollection> collection_;
other way, if you can ensure the NodeHandle destroy before TopicManage() destroy, it also fine, like below code:
int main(int argc, char* argv[]) {
ros::init(ros::VP_string(), "test");
std::shared_ptr<ros::NodeHandle> n;
n = std::make_shared<ros::NodeHandle>();
return 0;
}
int main(int argc, char* argv[]) {
ros::init(ros::VP_string(), "test");
static std::shared_ptr<ros::NodeHandle> n = std::make_shared<ros::NodeHandle>();
return 0;
}
when I run above code will crash, this crash message is:
coredump backstrace is: