求助,动手学ROS2“Action实现”章节中,运行控制节点时出现Segmentation fault错误无法解决
-
按照教程实现这一章节时,无论是CPP(手打)还是Python(完全复制)都出现了
[INFO] [1706555430.349412739] [action_control_02]: 节点已启动:action_control_02! [ros2run]: Segmentation fault
尝试使用gdb调试,错误信息
User (gdb) bt full #0 0x00007fffffff9fe0 in ?? () No symbol table info available. #1 0x00007ffff6a4e89d in eprosima::fastcdr::Cdr::serialize_member<float> ( header_selection=eprosima::fastcdr::Cdr::AUTO_WITH_SHORT_HEADER_BY_DEFAULT, member_value=@0x5555558b1c10: 10, member_id=..., this=0x7fffffffa000) at /home/meng/fastdds_ws/install/fastcdr/include/fastcdr/Cdr.h:2539 current_state = {offset_ = {buffer_ = 0x0, current_position_ = 0xffff00001fa0 <error: Cannot access memory at address 0xffff00001fa0>}, origin_ = {buffer_ = 0x7fffffffc130 "", current_position_ = 0x5555558b1c00 "@R\031/4N\237\214Lo\320\340\301\314\005\217"}, swap_bytes_ = 161, last_data_size_ = 140737336087730, next_member_id_ = {id = 4150139584, must_understand = 255, static member_id_invalid_value_ = 4294967295}, member_size_ = 0, header_selection_ = eprosima::fastcdr::Cdr::AUTO_WITH_SHORT_HEADER_BY_DEFAULT, header_serialized_ = eprosima::fastcdr::Cdr::SHORT_HEADER, previous_encoding_ = 127} current_state = <optimized out> #2 eprosima::fastcdr::Cdr::operator<< <float> (value=@0x5555558b1c10: 10, this=0x7fffffffa000) at /home/meng/fastdds_ws/install/fastcdr/include/fastcdr/Cdr.h:334 No locals. #3 eprosima::fastcdr::Cdr::operator<< <float> (value=@0x5555558b1c10: 10, this=0x7fffffffa000) --Type <RET> for more, q to quit, c to continue without paging--RET at /home/meng/fastdds_ws/install/fastcdr/include/fastcdr/Cdr.h:325 No locals. #4 robot_control_interfaces::action::typesupport_fastrtps_cpp::cdr_serialize ( ros_message=..., cdr=...) at /home/meng/ros2_ws/2_ws/build/robot_control_interfaces/rosidl_typesupport_fastrtps_cpp/robot_control_interfaces/action/detail/dds_fastrtps/move_robot__type_support.cpp:36 No locals. #5 0x00007ffff6a4ef11 in robot_control_interfaces::action::typesupport_fastrtps_cpp::cdr_serialize (ros_message=..., cdr=...) at /home/meng/ros2_ws/2_ws/build/robot_control_interfaces/rosidl_typesupport_fastrtps_cpp/robot_control_interfaces/action/detail/dds_fastrtps/move_robot__type_support.cpp:722 No locals. #6 0x00007ffff759186e in rmw_fastrtps_shared_cpp::TypeSupport::serialize(void*, eprosima::fastrtps::rtps::SerializedPayload_t*) () from /opt/ros/humble/lib/librmw_fastrtps_shared_cpp.so No symbol table info available. #7 0x00007ffff6ec94b2 in eprosima::fastdds::dds::DataWriterImpl::perform_create_new_change(eprosima::fastrtps::rtps::ChangeKind_t, void*, eprosima::fastrtps::rtps::WriteParams&, eprosima::fastrtps::rtps::InstanceHandle_t const&) () from /opt/ros/humble/lib/libfastrtps.so.2.6 No symbol table info available.
询问ChatGPT,回答为
这个 GDB 调试信息显示了在程序运行期间的调用栈。从中可以看到,程序在 Cdr::serialize_member<float> 函数中崩溃,这是 Fast DDS 的序列化库的一部分。 这可能是由于序列化过程中的内存访问错误引起的。在这里,value 指向的内存地址(@0x5555558b1c10)似乎无效,导致了段错误。 这里有几个可能的原因: 未正确初始化变量: 请确保在使用变量之前正确初始化它。在你的代码中,ros_message 可能没有被正确初始化。 内存破坏: 可能存在内存破坏或释放后使用的问题。检查你的代码,确保没有释放已经释放的内存,或者没有访问已经释放的内存。 Fast DDS 版本问题: 有时,Fast DDS 的不同版本之间可能会导致兼容性问题。确保你使用的 Fast DDS 版本与你的代码兼容。 在你的 GDB 会话中,你可以检查 ros_message 的值以及它所指向的内存是否正确初始化。此外,你还可以检查你的程序的其他部分是否正确使用了 Fast DDS 库。 请检查这些方面,看看是否能够找到问题的根本原因。如果有其他信息,可以提供更多的上下文。
回想起“使用DDS进行订阅发布”这一章节,安装正确,cmake后,执行make时出现报错
User meng@meng:~/dds_tutorial/examples/01-hellofishros/build$ make [ 12%] Building CXX object CMakeFiles/DDSHelloFishRosPublisher.dir/src/HelloFishRosPublisher.cpp.o In file included from /home/meng/dds_tutorial/examples/01-hellofishros/src/HelloFishRosPublisher.cpp:16: /home/meng/dds_tutorial/examples/01-hellofishros/src/idl_generate/HelloFishRosPubSubTypes.h:32:2: error: #error Generated HelloFishRos is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen. 32 | #error Generated HelloFishRos is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen. | ^~~~~ /home/meng/dds_tutorial/examples/01-hellofishros/src/HelloFishRosPublisher.cpp: In member function ‘void HelloWorldPublisher::run(uint32_t)’: /home/meng/dds_tutorial/examples/01-hellofishros/src/HelloFishRosPublisher.cpp:178:18: error: ‘std::this_thread’ has not been declared 178 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); | ^~~~~~~~~~~ make[2]: *** [CMakeFiles/DDSHelloFishRosPublisher.dir/build.make:76:CMakeFiles/DDSHelloFishRosPublisher.dir/src/HelloFishRosPublisher.cpp.o] 错误 1 make[1]: *** [CMakeFiles/Makefile2:85:CMakeFiles/DDSHelloFishRosPublisher.dir/all] 错误 2 make: *** [Makefile:91:all] 错误 2
GPT回答:
生成的 HelloFishRosPubSubTypes.h 与当前安装的 Fast DDS 不兼容。建议使用 fastddsgen 工具重新生成代码。 std::this_thread 没有被声明。这可能是由于没有正确包含头文件导致的。您需要确保您的源文件包含了正确的头文件。
以为只是不兼容,就没在意,可能这个有关系?
以为可能是FastDDS没安装成功,于是在终端里输入fastdds discovery -i 0 -t 127.0.0.1 -q 42100 -t 192.163.6.34 -q 42101
显示
### Server is running ### Participant Type: SERVER Security: NO Server ID: 0 Server GUID prefix: 44.53.00.5f.45.50.52.4f.53.49.4d.41 Server Addresses: TCPv4:[127.0.0.1]:42100-42100 TCPv4:[192.163.6.34]:42101-42101
也没问题,就不知道什么原因了。。。
-
ubuntu系统是22.04,使用小鱼的一键安装,ROS版本是humble
-
再次尝试排查错误,运行action_robot_02节点:
ros2 run example_action_rclpy action_robot_02 [INFO] [1706613897.098919743] [action_robot_02]: 节点已启动:action_robot_02!
新开终端,输入指令
ros2 interface show robot_control_interfaces/action/MoveRobot
显示:
# Goal: 要移动的距离 float32 distance --- # Result: 最终的位置 float32 pose --- # Feedback: 中间反馈的位置和状态 float32 pose uint32 status uint32 STATUS_MOVEING = 3 uint32 STATUS_STOP = 4
尝试手动发送动作,输入指令:
ros2 action send_goal /move_robot robot_control_interfaces/action/MoveRobot "{distance: 5.0}"
显示:
Waiting for an action server to become available... Sending goal: distance: 5.0 段错误 (核心已转储)
同时系统提示,ros2已崩溃,可以确定是发送动作指令出现了问题。
但是之前小乌龟节点发送指令一切正常,不知道怎么回事。
请大佬指点迷津 -
又测试了别的教程里的动作通讯,仍然会出现段错误。现在高度怀疑是FastDDS未安装成功。
https://fishros.com/d2lros2/#/humble/chapt3/advanced/3.DDS%E8%BF%9B%E9%98%B6%E4%B9%8BFast-DDS%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA
安装的过程是参考小鱼的这个教程,过程也挺不顺利。会不会是小鱼的这个教程和我的ROS humble版本不兼容?
-
进入FastDDS官网,按照说明一步步编译源码之后,重新运行,依然触发段错误。
使用gdb调试,将错误信息传入chatGPT,回答如下:在你的 backtrace 中,看起来程序在 Fast DDS 的序列化代码中遇到了一个问题,导致了段错误(Segmentation fault)。 具体来说,它在 eprosima::fastcdr::Cdr::serialize_member<float> 这个函数中发生了问题。该函数是 Fast DDS 库中用于序列化 float 类型成员的部分。问题可能是在序列化时访问了无效的内存地址,导致段错误。 由于 serialize_member 是 Fast DDS 的库函数,为了更深入地了解问题,你可能需要查看 Fast DDS 的源代码,尤其是与序列化相关的部分,以找出是什么导致了这个问题。 另外,你也可以尝试使用 Fast DDS 提供的调试工具和文档,以获取更多关于 Fast DDS 内部状态的信息。在这个过程中,你可能需要检查你的代码中是否有错误的序列化操作或与 Fast DDS 集成的其他问题。
感觉要排除FastDDS集成的问题,gradle是7.6版本,一切都很顺利。
难不成接下来要去看FastDDS 序列化部分的源代码了吗。。。 -
已解决。
看到一篇帖子和我一样的问题https://answers.ros.org/question/348971/segmentation-fault-with-sendinggoal-client-and-actionlib/
受到了启发,可能是ROS2内置了FastDDS,再次编译源码后导致重复。
删除源码后卸载重装ROS2,再次运行action节点,正常运行。
-
fast dds难用的一批,直接换cyclonedds的rmw。解决大部分中间件问题
-
大概率是跟着小鱼的进阶教程中https://fishros.com/d2lros2/#/humble/chapt3/advanced/3.DDS%E8%BF%9B%E9%98%B6%E4%B9%8BFast-DDS%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA((一)ROS2入门篇--->第 3 章 ROS2节点通信之话题与服务--->进阶篇-中间件进阶--->3.DDS进阶之Fast-DDS环境搭建),又手动下载编译了FastDDS,导致了与ros2内置的DDS出现冲突,只需要把创建的fastdds_ws工作空间删除,然后去~/.bashrc文件中配置的环境变量删除即可