ROS在线调试(使用GDB)

本文涉及的产品
资源编排,不限时长
简介: ROS在线调试(使用GDB)

引言


在写ROS工程代码,有时候找一个bug非常麻烦,尤其是运行时出错的bug,这时候借助一些调试器可以极大的提高查找bug的效率。


ROS官方列出了许多可用的IDE:http://wiki.ros.org/IDEs,如VScode, Qtcreator, Ecllipse, Clion等,而这些不方便快速的调试。


所以,下面介绍如何使用GDB调试器来进行ROS C++项目的调试


在debug模式编译


编译器有些优化会让debug无法进行。为了避免这种情况,程序编译时要加上debug选项,让cmake以debug模式编译,不然可能会在gdb调试的时候不能跳转到源代码,只能进入断点。


普通的非ROS程序用gdb怎么调试呢?在编译好后(编译的方法和正常的程序一样,不过要在cmakelists前面添加)


set(CMAKE_BUILD_TYPE Debug)


如果用命令行catkin_make,在输入catkin_make时加上一个参数:


catkin_make -DCMAKE_BUILD_TYPE=Debug


或者直接修改CMakelist.txt,添加以下代码,


SET(CMAKE_BUILD_TYPE "Debug")
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")


添加GDB调试指令 (launch)


修改ROS launch文件,在node标签中添加一句话


launch-prefix="xterm -e gdb -ex run --args "


修改后的launch文件如下所示


<node pkg="waypoint_follower" type="pure_persuit" name="pure_pursuit" output="screen" launch-prefix="xterm -e gdb -ex run --args">
        <param name="is_linear_interpolation" value="$(arg is_linear_interpolation)"/>
</node>


这样在执行原来例子的时候,就会先打开一个新的Shell界面,被调试的程序就在这个Shell中被执行了。


如果使用的是Python来写ROS,则需要修改调试器为pdb,如下:


launch-prefix="xterm -e python -m pdb "


附:roslaunch node前缀


The launch-prefix attribute of the tag that, among other things, makes it easy to debug a ROS node process. Here are some example launch-prefixes you might find useful:
launch-prefix=“xterm -e gdb --args” : run your node in a gdb in a separate xterm window, manually type run to start it
launch-prefix=“gdb -ex run --args” : run your node in gdb in the same xterm as your launch without having to type run to start it
launch-prefix=“stterm -g 200x60 -e gdb -ex run --args” : run your node in gdb in a new stterm window without having to type run to start it
launch-prefix=“valgrind” : run your node in valgrind
这个valgrind工具可以用于检测内存泄露,并执行性能分析
launch-prefix=“xterm -e” : run your node in a separate xterm window
launch-prefix=“nice” : nice your process to lower its CPU usage
launch-prefix=“screen -d -m gdb --args” : useful if the node is being run on another machine; you can then ssh to that machine and do screen -D -R to see the gdb session
launch-prefix=“xterm -e python -m pdb” : run your python node a separate xterm window in pdb for debugging; manually type run to start it


在使用roslaunch node debug.launch后会得到:


20200621141043474.png


添加GDB调试指令 (cmd)


跑ros程序的两个方法一个是rosrun,一个是roslaunch.roslaunch在上文已讲,下面就是使用cmd去跑rosrun,首先使用下面语句执行文件:


rosrun --prefix 'gdb -ex run --args' [package_name] [node_name]


执行完上面的语句,你会发现程序直接开始跑了,我还来不及设置断点什么的呢.问题应该出在run那个参数上,不过我暂时没找到替代的,得想想其他办法.

rosrun其实就相当于直接执行二进制文件./文件.那么我们直接找到catkin_make产生的二进制文件进行运行不就完了?每一个package产生的二进制文件存放的位置在


you_catkin_workspace/devel/lib/your_package_name


里.cd进去上面的地址,你应该能看到你在CMakeLists.txt里通过add_executable产生的那个二进制文件的名字(就是rosNode了).在terminal中输入


gdb node_name


就会发现进入gdb模式了,terminal的输出像下面这样


20200621140329463.png


这时候我们可以输入第三个链接pdf中的命令进行调试了.


设置断点


pdf中写的设置断点的方法为break <where>,这个where指的是程序的哪一行,例如,我在上面的程序的28行注释了一下line 28.我们在terminal中输入


break 28


会看到一则消息关于断点设置的.然后我们就可以跑程序了.在terminal中输入


run


我们根据terminal的输出应该能很轻易的知道28行程序暂停了.断点已经设置成功了.

另外也可以


break 函数名


设置断点,这样进入函数的时候程序会暂停


查看变量值 


现在我们要查看某个变量的值呢?pdf中显示是print/format <what>或者display/format <what>.what表示是什么变量.我们在terminal中输入


display count


便能看到程序中变量count的值了.


执行下一步


同样查看pdf得知,在terminal中输入next就可以了.


设置被包含的程序的断点


我们写大型程序的时候,一个rosnode肯定include了好多文件,上面的break 28默认在主函数中设置断点了,那么我们想在其他不在同一个cpp文件中的函数设置断点之类的呢?比如我们在CMakeLists.txt中编译的时候使用的下面语句


add_executable(main main.cpp b.cpp c.cpp)


之后使用


gdb main
1


进行调试,如果我们想在b.cpp中加一个断点,我们只需要在terminal中特殊指明是哪个cpp加上行数即可,比如


break b.cpp:line_number


其中line_number表示你想在b.cpp中的哪行代码添加breakpoint.


显示出错的位置


gdb调试出错了,比如出现segmentation fault,通常会自动显示出错位置,输入where可以显示出更详细的内容


退出gdb


程序正在运行,按下crtl+c,在输入q退出.

程序没有运行,直接输入q退出.


GDB基本命令


基本


命令

描述

gdb

打开调试器

file FILE

装载指定可执行文件
r

代表run,从头开始运行程序直到断点。在一次debug中你可以通过用 r 来多次重新运行程序,而不必重新rosrun 或 roslaunch.

q

退出debug

bt

列出调用堆栈


显示被调试文件信息


命令

描述

info files

显示被调试文件的详细信息

info func

显示所有函数名称

info local

显示当前函数中的局部变量信息

info prog

显示被调试程序的执行状态

info var

显示所有的全局和静态变量名称


查看/修改内存


命令

描述

p x

相当于“print x”。显示当前变量 x 的值。

display x

和print的区别是,x不是只显示一次就消失,而是一直显示,每次继续运行程序都会刷新。相当于VS的“watch”功能。

undisplay x

停止对变量x的display

x address

查看指针所指位置的值。

set x = 12 set

修改变量x的值。

call function()

调用某函数。这个函数可以是你程序里定义的函数,甚至是标准库函数,我的理解是只要在当前位置可访问到的函数都可以调用。这是一个极其有用的功能,生生把c++用成Matlab 。


断点


命令

描述

b

b即break。在当前行设置断点。

b 45

在某行设置断点。

b functionName

在某函数开始处设置断点。常用:b main 在程序开始设置断点。

watch x == 3

设置条件断点。这个比VS的条件断点更方便,因为它不需要设置在哪一行!时刻监控!

info break

查看当前存在的所有断点。每个断点都有自己的编号。

delete N

删除编号为N的那个断点。


调试运行


命令

描述

n

“next”。运行一行代码。 相当于VS的step over。

s

“step”。运行一个指令。相当于VS的step in。n和s都可以一次运行多行,比如n 5

c

“continue”。继续运行直到下一个断点。

f

“finish”,运行完当前程序。相当于VS的 step out。


相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
3月前
|
NoSQL Linux C语言
Linux GDB 调试
Linux GDB 调试
65 10
|
3月前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
102 3
|
3月前
|
NoSQL
技术分享:如何使用GDB调试不带调试信息的可执行程序
【8月更文挑战第27天】在软件开发和调试过程中,我们有时会遇到需要调试没有调试信息的可执行程序的情况。这可能是由于程序在编译时没有加入调试信息,或者调试信息被剥离了。然而,即使面对这样的挑战,GDB(GNU Debugger)仍然提供了一些方法和技术来帮助我们进行调试。以下将详细介绍如何使用GDB调试不带调试信息的可执行程序。
108 0
|
5月前
|
NoSQL Linux C语言
Linux gdb调试的时候没有对应的c调试信息库怎么办?
Linux gdb调试的时候没有对应的c调试信息库怎么办?
45 1
|
5月前
|
NoSQL Linux C语言
Linux gdb调试的时候没有对应的c调试信息库怎么办?
Linux gdb调试的时候没有对应的c调试信息库怎么办?
32 0
|
5月前
|
NoSQL Linux C++
Linux C/C++ gdb调试正在运行的程序
Linux C/C++ gdb调试正在运行的程序
|
5月前
|
NoSQL Linux C++
Linux C/C++ gdb调试core文件
Linux C/C++ gdb调试core文件
|
5月前
|
NoSQL Linux C++
Linux C/C++ gdb调试
Linux C/C++ gdb调试
|
6月前
|
NoSQL Ubuntu 测试技术
【GDB自定义指令】core analyzer结合gdb的调试及自定义gdb指令详情
【GDB自定义指令】core analyzer结合gdb的调试及自定义gdb指令详情
96 1
|
6月前
|
NoSQL 编译器 C语言
【GDB调试技巧】提高gdb的调试效率
【GDB调试技巧】提高gdb的调试效率
82 1

推荐镜像

更多
下一篇
无影云桌面