ros节点启动挂掉使用gdb调试——访问未初始化的内存错误

1.问题

在ros节点启动的时候,如果节点运行出问题会报错process has died,然后还会打印log日志,但是这个日志基本没什么用,里面一般不会打印哪个文件或者运行到哪出错误了,所以无法用于调试。实际比较快的定位错误还是要使用gdb。

2.gdb调试定位错误

  • 首先重新编译程序,把Release模式改成Debug模式。
  • 然后要根据运行的打印输出初步判断有可能是哪个节点出错,然后在运行这个节点的时候使用gdb
  • 在运行这个可能出错的节点的时候使用gdb,即在rosrun或者roslaunch后面加上prefix,然后再跟语句gdb -ex run --args使用gdb调试。如下:
# rosrun 
rosrun --prefix "gdb -ex run --args" feature_tracker feature_tracker

# 或者在launch文件中对launch增加:
 <name="feature_tracker" pkg="feature_tracker" type="feature_tracker" output="log" launch-prefix="gdb -ex run --args" >

注意

  • 上面如果是在命令行增加是用--prefix,在launch文件增加是用launch-prefix
  • 如果运行之后显示如下,说明不是这个节点没有错误,应该是其他节点出了问题,所以给其他节点用gdb重新测试即可,直到定位到错误。

在这里插入图片描述

3.问题解决

我遇到的错误使用gdb测试之后,定位的问题如下:
在这里插入图片描述
可以看到报错在系统库中了,但是一般系统库是不可能出问题的,所以这个使用基本上就要考虑代码的一些规范问题。

这里解释一下signal SIGSEGV, Segmentation fault这个错误,这个是内存访问错误,参考:调试中出现Programm received signal SIGSEGV, Segmentation fault原因及解决方法
这个信号产生的机制是由于程序访问了没有权限访问的内存,比如内存越界、线程栈溢出、指针未初始化或越界、访问到了未分配地址的空间等等。

所以这个时候仅仅使用gdb无法继续定位错误了,可以自己在程序中增加print输出,逐渐缩小范围查找变量的使用。

最后检查出上面的错误,是r2live的代码新增了READ_TIC/READ_RIC两个变量,而在使用的时候都是用了这俩,并且这俩是外参准确或者有估计值的时候赋值的,而我用的是在线估计外参的方式,因此这里就没赋值,导致最后报错。


版权声明:本文为qq_42731705原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。