鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    使用GDB调试ROS2程序

    已定时 已固定 已锁定 已移动
    ROS 2相关问题
    ros2 gdb
    3
    5
    1.9k
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • 首飞Kevin首
      首飞Kevin
      最后由 编辑

      我们使用backward_ros功能包来快速实现用GDB调试ROS2程序。

      backward_ros功能包介绍

      backward_ros功能包是对backward-cpp包的ROS2封装,以便可以简单快速地使用GDB工具。

      backward-cpp包的介绍可以查看其仓库:

      https://github.com/bombela/backward-cpp

      使用backward_ros功能包实现GDB调试ROS2程序只需下面三个步骤:

      1. 添加backward_ros到package.xml 文件。
      <depend>backward_ros</depend>
      
      1. 添加backward_ros到CMakeLists.txt文件中。
      find_package(backward_ros REQUIRED)
      
      1. 使用Debug 或者 RelWithDebInfo选项编译程序。
      colcon build --cmake-args '-DCMAKE_BUILD_TYPE=RelWithDebInfo'
      

      backward_ros功能包的github地址(ROS2程序使用foxy-devel分支):

      https://github.com/pal-robotics/backward_ros.git

      运行示例程序

      获取示例程序:

      git clone https://github.com/shoufei403/gdb_test.git
      

      编译时选择RelWithDebInfo或Debug编译类型时可以看到是代码的哪一行出了问题

      colcon build --cmake-args '-DCMAKE_BUILD_TYPE=RelWithDebInfo'
      

      运行测试程序

      source install/setup.bash
      ros2 run gdb_test gdb_test
      

      可以看到下面的堆栈信息

      Stack trace (most recent call last):
      #4    Object "", at 0xffffffffffffffff, in 
      #3    Source "/home/kevin/gdb_test/src/gdb_test/gdb_test.cpp", line 50, in _start [0x56060876e91d]
               47:   rclcpp::spin(std::make_shared<MinimalSubscriber>());
               48:   rclcpp::shutdown();
               49:   return 0;
            >  50: }
      #2    Source "../csu/libc-start.c", line 308, in __libc_start_main [0x7f1b2f271082]
      #1  | Source "/home/kevin/gdb_test/src/gdb_test/gdb_test.cpp", line 47, in make_shared<MinimalSubscriber>
          |    45: {
          |    46:   rclcpp::init(argc, argv);
          | >  47:   rclcpp::spin(std::make_shared<MinimalSubscriber>());
          |    48:   rclcpp::shutdown();
          |    49:   return 0;
          | Source "/usr/include/c++/9/bits/shared_ptr.h", line 718, in allocate_shared<MinimalSubscriber, std::allocator<MinimalSubscriber> >
          |   716:       typedef typename std::remove_cv<_Tp>::type _Tp_nc;
          |   717:       return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
          | > 718: 				       std::forward<_Args>(__args)...);
          |   719:     }
          | Source "/usr/include/c++/9/bits/shared_ptr.h", line 702, in shared_ptr<std::allocator<MinimalSubscriber> >
          |   700:     {
          |   701:       return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
          | > 702: 			     std::forward<_Args>(__args)...);
          |   703:     }
          | Source "/usr/include/c++/9/bits/shared_ptr.h", line 359, in __shared_ptr<std::allocator<MinimalSubscriber> >
          |   357:       template<typename _Alloc, typename... _Args>
          |   358: 	shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
          | > 359: 	: __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
          |   360: 	{ }
          | Source "/usr/include/c++/9/bits/shared_ptr_base.h", line 1344, in __shared_count<MinimalSubscriber, std::allocator<MinimalSubscriber> >
          |  1342:       template<typename _Alloc, typename... _Args>
          |  1343: 	__shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
          | >1344: 	: _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
          |  1345: 	{ _M_enable_shared_from_this_with(_M_ptr); }
          | Source "/usr/include/c++/9/bits/shared_ptr_base.h", line 679, in _Sp_counted_ptr_inplace<>
          |   677: 	  auto __guard = std::__allocate_guarded(__a2);
          |   678: 	  _Sp_cp_type* __mem = __guard.get();
          | > 679: 	  auto __pi = ::new (__mem)
          |   680: 	    _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
          |   681: 	  __guard = nullptr;
          | Source "/usr/include/c++/9/bits/shared_ptr_base.h", line 548, in construct<MinimalSubscriber>
          |   546: 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
          |   547: 	  // 2070.  allocate_shared should use allocator_traits<A>::construct
          | > 548: 	  allocator_traits<_Alloc>::construct(__a, _M_ptr(),
          |   549: 	      std::forward<_Args>(__args)...); // might throw
          |   550: 	}
          | Source "/usr/include/c++/9/bits/alloc_traits.h", line 483, in construct<MinimalSubscriber>
          |   481: 	construct(allocator_type& __a, _Up* __p, _Args&&... __args)
          |   482: 	noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
          | > 483: 	{ __a.construct(__p, std::forward<_Args>(__args)...); }
          |   484: 
          |   485:       /**
            Source "/usr/include/c++/9/new", line 174, in main [0x56060876e7b1]
              172: // Default placement versions of operator new.
              173: _GLIBCXX_NODISCARD inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
            > 174: { return __p; }
              175: _GLIBCXX_NODISCARD inline void* operator new[](std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
              176: { return __p; }
      #0    Source "/home/kevin/gdb_test/src/gdb_test/gdb_test.cpp", line 33, in MinimalSubscriber [0x56060878c1a8]
               30:       "topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1));
               31: 
               32:     int * p = nullptr;
            >  33:     *p = 1;//制造断错误
               34:   }
               35: 
               36: private:
      Segmentation fault (Address not mapped to object [(nil)])
      
      

      其他使用GDB的方法可以参考此文档

      https://navigation.ros.org/tutorials/docs/get_backtrace.html#preliminaries

      我是首飞,一位帮大家填坑的机器人开发攻城狮。

      小鱼小 1 条回复 最后回复 回复 引用 0
      • 小鱼小
        小鱼 技术大佬 @首飞Kevin
        最后由 编辑

        @首飞Kevin 赞,这个可以用vscode打短点调试吗,还是说把gdb的bt堆栈在终端打出来的功能

        新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

        首飞Kevin首 2 条回复 最后回复 回复 引用 0
        • 首飞Kevin首
          首飞Kevin @小鱼
          最后由 编辑

          @小鱼 段错误时会在命令窗口打印出堆栈信息。

          我是首飞,一位帮大家填坑的机器人开发攻城狮。

          1 条回复 最后回复 回复 引用 0
          • 首飞Kevin首
            首飞Kevin @小鱼
            最后由 编辑

            @小鱼 没有用vscode的,应该是打不了断点。

            我是首飞,一位帮大家填坑的机器人开发攻城狮。

            1 条回复 最后回复 回复 引用 0
            • 29076774812
              枕风宿雪
              最后由 编辑

              为啥我的只能打印一半呀,我的ROS2是安装在ARM64的Ubuntu系统中,大佬能解答一下吗,万分感谢!!! 48a6d6aa-4719-4397-82d3-5a74c10d3112-image.png

              1 条回复 最后回复 回复 引用 0
              • 第一个帖子
                最后一个帖子
              皖ICP备16016415号-7
              Powered by NodeBB | 鱼香ROS