簡體   English   中英

ROS cv_bridge::toCvCopy 因分段錯誤而失敗

[英]ROS cv_bridge::toCvCopy fails with segmentation fault

我遇到了一個奇怪的分段錯誤。 在 ROS 節點中執行cv_bridge::toCvCopy時,由於分段錯誤而失敗。 我確定給定的消息有數據,並且代碼包含在try...catch中。

ROS 版本:動力學,OpenCV 版本:2.4,Ubuntu 版本:16.04。

代碼:

#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)

從結果中可以看出,主題msg有正確的數據,並且cv_bridge::toCvCopy旁邊的行沒有執行,因此cv_bridge::toCvCopy發生了分段錯誤。

此外,我使用 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

但是我找不到錯誤的原因。 有人可以提出解決方案嗎?

我不知道為什么,但我通過在libcv-bridge0d package 中用libcv_bridge.so.0d替換/opt/ros/kinetic/lib/libcv_bridge.so解決了這個問題。

詳細流程:

$ 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

我在 Python 也遇到了類似的問題,可以通過以下方式解決:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM