前言

最近突然沉迷b站up主“城阳电工电路”的视频,看着每一次排查电路问题的过程,就好像自己debug程序问题的感受,代入感非常强烈。最近编译一个ros项目时,由于版本不一致的原因,也遇到了不少编译错误。让我最后非常有成就感的是,这一次的debug过程脑子全程在线,没有卡壳,从假设到验证,层层递进,直达问题根源,而且大部分的错误都是用这一个思路解决的。最后解决问题的时候,真就感觉仿佛“名侦探”断案,脑海中闪过那句经典名言——“新几次瓦一字莫黑道次!”。来跟我复现一下这一气呵成的一次debug过程吧!

开端

在编译github上的一个ros仓库时,由于作者使用的是Ubuntu 16.04的ROS版本kinetic,而我自己则是18.04的melodic的ROS版本,编译时自然而然就出现了问题。


从error的地方可以看到报错原因是“执行了一个不可用的变换转换”,乍一听云里雾里不知所云。不过上一行就提示了出错代码段的位置位于hand_eye_move.cpp的132行,不如先去看一下源代码再判断。


可以看到132行是visual_tools对象调用了publishText()方法,其中第一个参数text_pose我们可以从这个函数的形参类型中知道它是Eigen库中Affine3d类型的矩阵,后面三个参数,一个是字符串,另外两个看起来也像是属性描述之类的作用,似乎都不太重要。联想到我们报错的问题,大概率是这个矩阵变量的问题。从函数的形参里可以知道visual_toolsmoveit_visual_tools::MoveItVisualTools类中的一个对象,而在编译前安装过ros-melodic-moveit-visual-tools这个工具,是不是可能随着版本的更新,这个对象中的方法原型发生了变化导致了现在的报错呢?那么不如我们接着往下,去看一下publishText()这个方法的函数原型吧。

发展

这个时候疑惑的地方来了,打开了MoveItVisualTools类所在的头文件moveit_visual_tools.h,用CLion左边栏的Structure功能去看有哪些方法,竟然没有publishText()这个方法。


我用字母表顺序排列所有的方法名,很显然没有,顿时感觉很奇怪,不过很快想到,也许这个包在版本迭代过程中进行了大更新,把函数名都修改了。顺着这个想法,我直接奔着ros-melodic-moveit-visual-tools这个包的github仓库看一下moveit_visual_tools.h文件的历史提交。


从2014年首次提交到2015年最后一次,一共也就这几次提交,索性全部找一遍,当然我直接先去看了最初的提交版本。令我惊讶的是,最初的版本和现在版本的函数类别数量差不多,并且没有我们要找的publishText(),我又去看了另外的提交版本,也没有。那publishText()这个方法没有,其他调用的方法比如deleteAllMarkers()有没有呢?找了一遍,还是没有。抱着疑惑的心情,我想,既然moveit_visual_tools.h中没有定义publishText()deleteAllMarkers()等这几个的方法,而且编译时报错也不像是缺少头文件的样子,那我倒要看看这几个方法在哪个文件里。这时就要祭出万能的Linux shell了,用find和xargs的管道,找出包含“publishText()”字段的文件。想到大概率还是ros原生的方法,查找目录就定在ros的安装目录/opt/ros,直接执行find /opt/ros/ | xargs grep -ril "publishText"


有结果打印就是振奋人心的,什么???竟然在rviz_visual_tools.h里。满怀期待同时又很不解,直接打开文件看方法原型。
瞧瞧,这不就来了吗?有了函数原型,我们可以很明显地看到有关pose这个形参的类型定义是不相同的,出错源代码中是Affine3d,而在这里则是Isometry3d。凭借“多年”debug的直觉,可以确定问题出在这里了,不过为了验证一下自己的猜想,我又跑到github上去看了下rviz_visual_tools.h的历史提交,果不其然,在publishText()这一方法的首次提交的commit中,看到了最初的函数原型。

从912行看到,pose形参的最初类型就是Affine3d,和我们的猜想一致,确定是在版本迭代过程中,publishText()方法的第一个形参类型发生了变化,实际上如果用原先类型Affine3d定义一个矩阵变量,作为参数传入现在的Isometry3d定义的函数中时,的确可能会执行某种conversion操作,报之前的错误也不足为奇了。

高潮

到了这里,依然有个疑问,为什么原先类的定义中没有。。。马萨卡!(PS:此时一道闪电划过脑壳)
我知道犯人是谁了,不是,我知道为什么了。

【沉睡的小五郎】犯人就是“继承(Inheritance)”!moveit_visual_tools.h中的类MoveItVisualTools应该继承了rviz_visual_tools.h的定义,调用的publishText()是父类的方法,只要查看moveit_visual_tools.h文件的开头,真相就会大白!

结局

此时此刻,犯人(我)直接跪下,痛苦流涕,“是我太菜了,C++学艺不精,呜哇呜哇~”。
将原先使用Affine3d定义的矩阵变量修改为Isometry3d之后,编译就通过了。

总结

柯南入戏太深了属于是233。回顾这一次debug的过程,如果对ros或c++的实践经历更加丰富,其实很容易想到调用了父类的方法,奈何自己学艺不精,阅历尚浅,才有了这次虽然很爽但是又很显笨拙的debug经历。不过自我感觉这次的debug实践还是比较考验思路和能力的,因此就有感而发记录下来,当然自己还需要学习的地方还有很多很多,还需要再接再厉!

“名侦探”兔哥上线——记一次从蛛丝马迹中debug问题的经历相关推荐

  1. 记一次在VMware中安装黑苹果的经历

    前言 最近想安装一个黑苹果试试水,但是看网上很多教程说可能硬件不匹配导致一些硬件不能用,所以想先在虚拟机安装一个看看 正文 1.首先是需要的资源的下载链接,直接在百度网盘下载即可. 链接:https: ...

  2. 导出滴滴行程单_身穿统一的绿马甲!滴滴货运小哥上线首日即爆单

    最近,杭州的滴滴用户打开滴滴出行App就能看到一个新的"货运"选项.昨天,滴滴货运正式在杭州和成都两城上线,为用户提供同城货运服务. 昨天上午,记者来到位于杭州城北的建华市场,这是 ...

  3. HHUOJ 1862 帮助名侦探

    HHUOJ 1862 帮助名侦探 题目描述 柯南一行人来到了美丽的海滨城市度假.但是,常言说得好,柯南到哪哪死人.这不,他们刚一来,这座城市就发生了连环杀人案--当地警方得知柯南一行人恰好在这座城市, ...

  4. Cocos2d-x 3.8.1+Cocos Studio 2.3.2捉虫记之控制场景文件中的骨骼动画

    Cocos2d-x 3.8.1+Cocos Studio 2.3.2捉虫记之控制场景文件中的骨骼动画 引子 这段时间一直努力在把早期版本的拇指接龙游戏(Cocos2d-x 2.2.3+CocoStud ...

  5. 记一次服务器被挖矿木马攻击的经历

    背景 利用空余时间买了台服务器做了个小网站玩,今天访问了一下,加载巨慢,一看服务器运行情况,CPU飙到100%,按CPU消耗排序,排在第一的是一个名为"imWBR1"的进程,查了一 ...

  6. Java黑皮书课后题第9章:**9.13(Location类)设计一个名为Location的类,定位二维数组中的最大值及其位置。

    Java黑皮书课后题第9章:**9.13(Location类)设计一个名为Location的类,定位二维数组中的最大值及其位置 题目 破题 代码 Test13 Test13_Location 运行结果 ...

  7. C语言试题五十一之已知学生的记录是由学号和学习成绩构成,n名学生的数据已存入s结构体数组中。请编写函数fun,该函数的功能是:找出成绩最高的学生记录,通过形参返回主函数(规定只有一个最高分)。

    1. 题目 请编写一个函数void function(Student a[], int n, Student *s),其功能时:已知学生的记录是由学号和学习成绩构成,n名学生的数据已存入s结构体数组中 ...

  8. 记一次rc.local中python脚本无法运行的解决过程

    记一次rc.local中python脚本无法运行的解决过程 问题记录: 解决过程: 1. 检查/etc/rc.local的权限 2. 看运行出错日志 3. 修改文件不重启啊(用户切换到root了,我再 ...

  9. 编写名为censor的函数,用来把字符串中出现的每一处字母“foo”替换成“xxx”。例如,字符串“food fool”会变为“xxxd xxxl”。再不失清晰性的前提下程序越短越好

    编写名为censor的函数,用来把字符串中出现的每一处字母"foo"替换成"xxx".例如,字符串"food fool"会变为"x ...

最新文章

  1. Runtime.getRuntime()
  2. 数列分块入门2(区间小于c的个数)
  3. 服务器tcp连接占满_漫画 | 一台Linux服务器最多能支撑多少个TCP连接?
  4. 火狐浏览器服务器意外响应,Firefox 火狐浏览器 83 发布,已修复任意代码执行漏洞...
  5. sql 2012先分离迁移mdf mlf 文件到别的机器后附加 数据库成只读的修复方法
  6. switch最大选项数目_随时随地学习C语言之3—if和switch哪个效率高?
  7. C 的 6 种内存顺序,你都知道吗?
  8. mysql heartbeat 慢_Mysql 慢日志优化分析方法
  9. 口红机源码运营版对接CC支付源码
  10. verilog学习记(加法器)
  11. jenkins运行web自动化测试找不到文件file not found
  12. 7-2 查找指定字符 (15 分)
  13. matlab 弹簧,利用Matlab进行弹簧振子运动
  14. viper12a电源电路图_采用VIPer12A的开关电源电路分析(图)
  15. MATLAB-Control System Toolbox™0.控制系统工具箱说明
  16. windows之电脑开机出现 this product is covered by one or more of the following prtents
  17. 金彩教育:选择关键词要参考哪些数据
  18. 微信公众号实现微信支付(含前后端完整代码)
  19. VS2010如何添加MSCOMM控件
  20. FUZ 1759 Super A^B mod C (指数循环节/模板)

热门文章

  1. mysql select 时间格式_Mysql格式化日期
  2. ae中心点重置工具_锚点中心点移动对齐工具Move Anchor Point v4.0.2 AE脚本下载
  3. Doris 数据类型
  4. DIV不换行与DIV换行 DIV默认自动换行
  5. shell之tail
  6. DH2F200N6S-ASEMI快恢复模块比快恢复二极管好在哪里?
  7. kodi没有中文设置_kodi播放器如何设置为中文界面-kodi播放器设置中文的方法 - 河东软件园...
  8. 工业控制系统安全控制列表
  9. 写一篇2000字的关于磁浮列车研究背景及意义的文章
  10. 开发的vscode插件,如何在用户卸载该插件时,删除该插件对应的文件