ROS下如何Debug?5分钟快速入门

2017-01-04 10:31:33来源:作者:炼数成金 - 商业智能人点击

第七城市

最受欢迎的开源机器人操作系统ROS已经九岁了。ROS给机器人系统的进程间通讯提供了一个统一的,跨平台的框架,这给经常连接几十个各种各样设备的机器人应用带来了非常大的便利。我也很喜欢使用ROS,以前打Robocup的时候,整个人形机器人的上层控制系统就是全部基于ROS Groovy写的。那时候开发和Debug主要靠Qt,反正队里有大神搞定编译的问题。

但如果不能用Qt之类的IDE呢?其实和其他Linux编程一样,用命令行有很方便而且很轻便的工具,只是上手未必容易。今天这篇文章我们把命令行下Debug ROS程序的流程整个梳理一遍,看完你会发现,其实并不复杂!

我们使用的主要工具是GDB。这是Linux诸多c/c++ debug工具中最流行的一种。只要你装了gcc(这是大多数Linux系统的默认c/c++编译器),GDB一般都捆绑安装过了。本文只讨论使用c++的 ROS程序。Python有PDB,我还不了解。

如果有更好的方法欢迎留言讨论!

步骤一 Build with debug label

编译器有些优化会让debug无法进行。为了避免这种情况,程序编译时要加上debug选项。

如果你用Catkin,用catkin_make 时加上一个参数:

catkin_make -DCMAKE_BUILD_TYPE=Debug

如果你想给Release版本Debug,就这样

catkin_make -DCMAKE_BUILD_TYPE=RelWithDebInfo

如果你用Rosbuild,在你的CMakeLists.txt靠近顶部的位置加上这样一句即可:

set(ROS_BUILD_TYPE Debug)

步骤二 在GDB里运行程序

如果你用roslaunch,在你的launch文件里,要debug的node那行加上

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

其中xterm可以换成任何你喜欢的终端。我比较推荐terminator, 因为方便划分窗口。

用Roslaunch还有几种不同的参数来调用GDB,详见引用3 。

如果你用rosrun,直接在调用的时候加上gdb的参数:

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

步骤三 开始Debug!

完成了步骤二并开始运行程序后,你的node会在GDB的管理下运行。你可以逐行运行程序,设置断点,并查看内存等等。如果跑蹦了,GDB会停在崩掉的那一行,你可以查看到底发生了什么事。GDB是命令行程序,你和它的交互全是通过敲指令实现的。GDB的详细用法是有一本书的:

如果你打算为GDB开发做点贡献,请立即关掉这篇文章并去认真研读一下这本书。如果你像我一样只是想快速上手GDB搞清楚自己的程序为什么炸了, 请继续往下读。这里我总结了一些常用的命令,按功能分成几类。刚开始用GDB的时候,基本上照着这个列表找指令就足够用了。

基本

r

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

q

退出debug。

查看代码/导航

l

列出当前所在文件的前10行。

l 50

列出当前所在文件从第50行开始的10行。

l functionName

列出当前所在文件从某函数开始的10行。

bt

“Backtraces”,列出调用堆栈。

up/down

在堆栈中向上/向下移动一级。可以简写为u和d

查看/修改内存

p x

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

x address

查看指针所指位置的值。

set x = 12

set x = y

修改变量x的值。

call function()

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

display x

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

undisplay x

停止对变量x的display。

断点

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。

其实常用的指令就那么几个,用几次很快就熟练了。

希望对你有用。新年快乐!

资料来源:

http://answers.ros.org/question/35218/how-to-compile-package-with-debug-option/

Rosrun:

http://answers.ros.org/question/222530/running-rosrun-with-gdb/

Roslaunch:

http://wiki.ros.org/roslaunch/Tutorials/Roslaunch%20Nodes%20in%20Valgrind%20or%20GDB

GDB

https://www.tutorialspoint.com/gnu_debugger/gdb_quick_guide.htm

欢迎加入本站公开兴趣群

商业智能与数据分析群

兴趣范围包括各种让数据产生价值的办法,实际应用案例分享与讨论,分析工具,ETL工具,数据仓库,数据挖掘工具,报表系统等全方位知识

QQ群:81035754

第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台