Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

c++ - ROS cv_bridge::toCvCopy fails with segmentation fault

I'm experiencing a weird segmentation fault. When executing cv_bridge::toCvCopy in a ROS node, it fails with segmentation fault. I'm sure that the given message has data, and the code is enclosed with try...catch.

ROS version: kinetic, OpenCV version: 2.4, Ubuntu version: 16.04.

Code:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>

void ImageCallback(const sensor_msgs::ImageConstPtr& msg)
{
  std::cerr<<"msg->header: "<<msg->header<<std::endl;
  std::cerr<<"msg->height: "<<msg->height<<std::endl;
  std::cerr<<"msg->width: "<<msg->width<<std::endl;
  std::cerr<<"msg->encoding: "<<msg->encoding<<std::endl;
  std::cerr<<"msg->is_bigendian: "<<int(msg->is_bigendian)<<std::endl;
  std::cerr<<"msg->step: "<<msg->step<<std::endl;
  std::cerr<<"msg->data.size(): "<<msg->data.size()<<std::endl;
  std::cerr<<"msg->data[0,1,2]: "<<int(msg->data[0])<<" "<<int(msg->data[1])<<" "<<int(msg->data[2])<<std::endl;
  std::cerr<<"msg->data[size()-1]: "<<int(msg->data[msg->data.size()-1])<<std::endl;
  std::cerr<<"msg->data[size()-2]: "<<int(msg->data[msg->data.size()-2])<<std::endl;
  std::cerr<<"msg->data[size()-3]: "<<int(msg->data[msg->data.size()-3])<<std::endl;
  cv_bridge::CvImagePtr cv_ptr;
  try
  {
    cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
    std::cerr<<"debug.p1"<<std::endl;
  }
  catch (cv_bridge::Exception& e)
  {
    ROS_ERROR("cv_bridge exception: %s", e.what());
    return;
  }
  std::cerr<<"cv_ptr: "<<cv_ptr<<std::endl;
  std::cerr<<"cv_ptr->image: "<<cv_ptr->image<<std::endl;
  cv::Mat frame= cv_ptr->image;

  cv::imshow("camera",frame);
  char c(cv::waitKey(1));
  if(c=='x1b'||c=='q')  ros::shutdown();
}

int main(int argc, char**argv)
{
  ros::init(argc, argv, "sub_img_node");
  ros::NodeHandle node("~");
  std::string img_topic("/camera/color/image_raw");
  if(argc>1)  img_topic= argv[1];

  cv::namedWindow("camera",1);
  ros::Subscriber sub_img= node.subscribe(img_topic, 1, &ImageCallback);
  ros::spin();
  return 0;
}

Output:

msg->header: seq: 352
stamp: 1610458354.727051013
frame_id: head_camera

msg->height: 480
msg->width: 640
msg->encoding: rgb8
msg->is_bigendian: 0
msg->step: 1920
msg->data.size(): 921600
msg->data[0,1,2]: 207 224 219
msg->data[size()-1]: 209
msg->data[size()-2]: 212
msg->data[size()-3]: 201
Segmentation fault (core dumped)

From the result, we can see that the topic msg has data correctly and the line next to cv_bridge::toCvCopy is not executed, so the segmentation fault happened at cv_bridge::toCvCopy.

Furthermore, I analyzed the core dump with gdb:

GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bin/sub_img_node...done.
[New LWP 101971]
[New LWP 101976]
[New LWP 101983]
[New LWP 101984]
[New LWP 101981]
[New LWP 101972]
[New LWP 101982]
[New LWP 101974]
[New LWP 101975]

warning: Unexpected size of section `.reg-xstate/101971' in core file.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `bin/sub_img_node /usb_cam/image_raw'.
Program terminated with signal SIGSEGV, Segmentation fault.

warning: Unexpected size of section `.reg-xstate/101971' in core file.
#0  0x00007fb2f5026b44 in cv::_InputArray::type(int) const () from /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4
[Current thread is 1 (Thread 0x7fb2f628fac0 (LWP 101971))]
(gdb) bt
#0  0x00007fb2f5026b44 in cv::_InputArray::type(int) const () from /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4
#1  0x00007fb2efa655bc in cv::cvtColor(cv::_InputArray const&, cv::_OutputArray const&, int, int) ()
   from /opt/ros/kinetic/lib/x86_64-linux-gnu/libopencv_imgproc3.so.3.3
#2  0x00007fb2f5505cf3 in cv_bridge::toCvCopyImpl(cv::Mat const&, std_msgs::Header_<std::allocator<void> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
   from /opt/ros/kinetic/lib/libcv_bridge.so
#3  0x00007fb2f5506103 in cv_bridge::toCvCopy(sensor_msgs::Image_<std::allocator<void> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /opt/ros/kinetic/lib/libcv_bridge.so
#4  0x00007fb2f55061e0 in cv_bridge::toCvCopy(boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /opt/ros/kinetic/lib/libcv_bridge.so
#5  0x00000000004074fb in ImageCallback (msg=...) at /home/akihikoy/prg/ay_test/ros/cpp_ros/test2/src/sub_img_node.cpp:49
#6  0x000000000040a91b in boost::function1<void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&>::operator() (a0=..., 
    this=<optimized out>) at /usr/include/boost/function/function_template.hpp:773
#7  boost::detail::function::void_function_obj_invoker1<boost::function<void (boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&)>, void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> >::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const>) (function_obj_ptr=..., a0=...) at /usr/include/boost/function/function_template.hpp:159
#8  0x000000000040af63 in boost::function1<void, boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> >::operator() (a0=..., this=<optimized out>)
    at /usr/include/boost/function/function_template.hpp:773
#9  ros::SubscriptionCallbackHelperT<boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > const> const&, void>::call (this=0x12915e0, params=...)
    at /opt/ros/kinetic/include/ros/subscription_callback_helper.h:144
#10 0x00007fb2f5ec2e2d in ros::SubscriptionQueue::call() () from /opt/ros/kinetic/lib/libroscpp.so
#11 0x00007fb2f5e686f8 in ros::CallbackQueue::callOneCB(ros::CallbackQueue::TLS*) () from /opt/ros/kinetic/lib/libroscpp.so
#12 0x00007fb2f5e6a0fb in ros::CallbackQueue::callAvailable(ros::WallDuration) () from /opt/ros/kinetic/lib/libroscpp.so
#13 0x00007fb2f5ec6ef9 in ros::SingleThreadedSpinner::spin(ros::CallbackQueue*) () from /opt/ros/kinetic/lib/libroscpp.so
#14 0x00007fb2f5eabedb in ros::spin() () from /opt/ros/kinetic/lib/libroscpp.so
#15 0x0000000000406276 in main (argc=2, argv=0x7ffe650933c8) at /home/akihikoy/prg/ay_test/ros/cpp_ros/test2/src/sub_img_node.cpp:78

However I could not find the reason of the error. Could anyone suggest a solution?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I do not why, but I solved this issue by replacing /opt/ros/kinetic/lib/libcv_bridge.so with libcv_bridge.so.0d in the libcv-bridge0d package.

Detailed procedure:

$ sudo apt-get -f install libcv-bridge0d
$ cd /opt/ros/kinetic/lib/
$ sudo mv libcv_bridge.so{,.trouble}
$ sudo ln -s /usr/lib/x86_64-linux-gnu/libcv_bridge.so.0d libcv_bridge.so

Also I had a similar trouble in Python, which could be solved by this:

$ sudo apt-get -f install python-cv-bridge

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...