Boost mutex error when using SimpleActionClient with std::unique_ptr

asked 2019-06-24 21:44:00 -0500

Rufus gravatar image

updated 2019-06-24 22:22:51 -0500

The minimal example that reproduces the issue (modified from this example) is as follows

#include <memory>
#include <gtest/gtest.h>
#include <actionlib/TestAction.h>
#include <actionlib/client/simple_action_client.h>

using namespace actionlib;

std::unique_ptr<SimpleActionClient<TestAction>> client;

TEST(SimpleClient, easy_wait_test)
{

  bool started = client->waitForServer(ros::Duration(10.0));
  ASSERT_TRUE(started);

  TestGoal goal;
  SimpleClientGoalState state(SimpleClientGoalState::LOST);

  goal.goal = 1;
  state = client->sendGoalAndWait(goal, ros::Duration(10,0), ros::Duration(10,0));
  EXPECT_TRUE( state == SimpleClientGoalState::SUCCEEDED)
    << "Expected [SUCCEEDED], but goal state is [" << client->getState().toString() << "]";

  goal.goal = 4;
  state = client->sendGoalAndWait(goal, ros::Duration(2,0), ros::Duration(1,0));
  EXPECT_TRUE( state == SimpleClientGoalState::PREEMPTED)
    << "Expected [PREEMPTED], but goal state is [" << client->getState().toString() << "]";
}

void spinThread()
{
  ros::NodeHandle nh;
  ros::spin();
}

int main(int argc, char **argv){
  testing::InitGoogleTest(&argc, argv);

  ros::init(argc, argv, "simple_client_test");

  client = std::unique_ptr<SimpleActionClient<TestAction>>(new SimpleActionClient<TestAction>("/my_action", true));

  boost::thread spin_thread(&spinThread);

  int result = RUN_ALL_TESTS();

  ros::shutdown();

  spin_thread.join();

  return result;
}

The error message (regardless of whether or not the tests succeed):

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::lock_error> >'
  what():  boost: mutex lock failed in pthread_mutex_lock: Invalid argument
edit retag flag offensive close merge delete

Comments

I have been meaning to look into this error for awhile, it happens on every ros test that we run.

Link gravatar image Link  ( 2019-06-25 04:46:57 -0500 )edit

try transposing the line ros::shutdown() with spin_thread.join(). I think these are issues where an object is destroyed in one thread while another thread is using it. In this case I think this might be the ros::NodeHandle existing after ros::shutdown()

PeterMilani gravatar image PeterMilani  ( 2019-12-03 09:49:45 -0500 )edit

The problem is that your unique_ptr never goes out of scope because it is global. Put "client.reset(nullptr);" before ros::shutdown().

mschickler gravatar image mschickler  ( 2020-07-09 17:28:48 -0500 )edit