【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
前面的文章,我们学习了如何仿真、如何编译代码、如何写代码。但是如何调试这些代码,涉及的不是很多。因为如果要把ros真的用起来,真正服务于自己的项目当中去,代码调试肯定是少不了的。不管是添加新的功能、还是对性能进行优化,都少不了代码调试的部分。鉴于目前大部分ros都是运行在linux环境下面,所以我们一般都会选择gdb来进行代码调试。 为了说明如何用gdb调试,我们下面来说一下具体的流程。

这是基本步骤,没有roscore,其他的node都没有办法正常运行。
这里测试程序选择一个以前编译过的代码,vel_node。直接输入rosrun beginner_tutorials vel_node即可。
既然roscore和node都已经运行起来了,那么这个时候需要知道vel_node究竟运行在那个process上面。这一步可以通过ps aux | grep vel_node来解决。
- feixiaoxing@feixiaoxing-VirtualBox:~/Desktop/catkin_ws$ ps aux | grep vel_node
- feixiao+ 2163 0.3 0.6 283364 19324 pts/1 Sl+ 17:03 0:00 /home/feixiaoxing/Desktop/catkin_ws/devel/lib/beginner_tutorials/vel_node
- feixiao+ 2207 0.0 0.0 17676 652 pts/2 S+ 17:04 0:00 grep --color=auto vel_node
bind的操作过程中,有一步时需要注意的。那就是bind的时候一定要添加sudo命令,不然bind不上。接下来如果我们能看到下面这些打印,基本上说明gdb已经成功bind上process 2163了。这个2163就是刚刚用ps aux | grep vel_node命令查找出来的process id。
- feixiaoxing@feixiaoxing-VirtualBox:~/Desktop/catkin_ws$ sudo gdb attach 2163
- [sudo] password for feixiaoxing:
- GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
- Copyright (C) 2020 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"...
- attach: No such file or directory.
- Attaching to process 2163
- [New LWP 2175]
- [New LWP 2176]
- [New LWP 2177]
- [New LWP 2178]
- [Thread debugging using libthread_db enabled]
- Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
- 0x00007faa8a84123f in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=0x7ffcdeee5190, rem=0x7ffcdeee51a0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
- 78 ../sysdeps/unix/sysv/linux/clock_nanosleep.c: No such file or directory.
后面的调试就是正常的gdb调试了,输入对应的gdb调试指令就可以了。不过我们用的比较多的还是bt,这里输入bt查看一下,
- (gdb) bt
- #0 0x00007faa8a84123f in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=0x7ffcdeee5190, rem=0x7ffcdeee51a0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
- #1 0x00007faa8a846ec7 in __GI___nanosleep (requested_time=<optimized out>, remaining=<optimized out>) at nanosleep.c:27
- #2 0x00007faa8ab6d351 in ros::ros_wallsleep(unsigned int, unsigned int) () from /opt/ros/noetic/lib/librostime.so
- #3 0x00007faa8ab6da5f in ros::Duration::sleep() const () from /opt/ros/noetic/lib/librostime.so
- #4 0x00007faa8ab6ce5a in ros::Rate::sleep() () from /opt/ros/noetic/lib/librostime.so
- #5 0x0000557a30c94acb in main ()
从打印来看应该问题不大了。有的同学也许会说,如何从main一开始执行的时候就能断住程序呢。方法很简单,就是在main.c入口处添加这样的debug代码就可以,
- while(!debug)
- {
- usleep(10000);
- }
这样等程序被gdb捕获之后,通过print debug=1的方法就可以继续调试main.c后面的代码了。大家可以自己多多练习测试下。
调试的时候,最好加一下-g选项,
- add_definitions("-Wall -g")