前言:

工作中,有使用过乐动ld06款激光雷达,此款雷达将常规雷达的转动的电机部分内置于自己的保护罩内,减少了雷达本身转动积灰等其他外界影响,探测半径是12m,是一款不错的雷达。

不过今天的主要内容不是介绍该雷达的性能,而是分享我在使用该雷达过程中,在进行项目开发中,发现一个在官方SDK中隐藏的问题,这个问题,在使用过程中,导致了进程的崩溃。

terminate called after throwing an instance of 'std::bad_alloc'what():  std::bad_alloc
[laser-2] process has died [pid 2323, exit code -6]

作者:良知犹存

转载授权以及围观:欢迎关注微信公众号:羽林君

或者添加作者个人微信:become_me


ld06介绍:

下面是官方对这款雷达的介绍:

LD06 主要由激光测距核心,无线传电单元,无线通讯单元,角度测量单元、电机驱动单元和机械外壳组成。
LD06 测距核心采用 DTOF 技术,可进行每秒 4500 次的测距。每次测距时,LD06 朝前发
射出红外激光,激光遇到目标物体后被反射到单光子接收单元。由此,我们获取到了激光的发
出时间和单光子接收单元收到激光的时间,两者的时间差即光的飞行时间,飞行时间再结合光
速即可解算出距离。

情况介绍:

最近使用乐动雷达时候,进行了一个上电下电读取数据的疲劳测试,经过脚本频繁的执行后,代码出现了崩溃。

最后面检查发现是一处浮点计算转换导致内存分配溢出的问题,而问题出现部分是官方包的计算没有做一些数据健壮的判断,最终导致了崩溃。

上面是代码原理,而从使用场景分析的话,出现这个问题的原因是,我们在进行机器断电再次上电时候,激光发生器有数据可以获得,但是雷达的电机没有转起来,这个时候计算的角度步长大小为一个异常值。

bug出现

代码在运行中,使用脚本进行改设备的有规律的上下电操作之后,出现了进程死掉的log展示

出现了此问题,第一时间是看log,但是log中没有什么有用的信息,所以我开始了gdb调试coredump文件

gdb分析

gdb exec coredump

展开之后使用bt命令就明显看到了内存溢出的问题

看到第 16 帧可能为异常发生的地方

(gdb) f 16
#16 LiPkg::ToLaserscan (this=this@entry=0x55679e90b0, src=...) at /usr/src/debug/ld06-driver/git-r0/git/sdk/src/lipkg.cpp:239
239 in /usr/src/debug/ld06-driver/git-r0/git/sdk/src/lipkg.cpp
(gdb) info locals
angle_increment = <optimized out>
beam_size = 4294967295

使用info locals之后看到此处函数里面beam_size为异常值

这里面我们看到beam_size算到了4294967295这样的一个值,这个值也是一个特殊值,42亿,是u32的最大值。

此外我们还在堆栈信息里面看到,改变量传入构造了一个vector,其中__n是很大的一个值

 0x00000055595e66e4 in std::vector<float, std::allocator<float> >::assign (__val=@0x7f8e189790: nan(0x400000), __n=4294967295, this=0x55679e9270) at /usr/include/c++/9.1.0/bits/stl_vector.h:746

所以我们打开相应的文件
vi usr/include/c++/9.1.0/bits/stl_vector.h +746

经过查看,我们发现__n 就是vector元素的计数,到这里,我们就明白了,是beam_size计算出错,导致的后面vector使用撑爆了。

打开执行的sdk源码,我们查看一下beam_size是怎么计算和使用的

我们看到 beam_size 为unsigned int,而计算它的数据都是float类型,而赋值的时候beam_size也没有用安全转换函数,那么我们基本可以肯定这应该是一次float类型转换的问题,那么看看数据到底是怎么算过来的呢。由于gdb调试的信息还是不够,所以我在下面又增加了log进行辅助分析。

增加log分析

在代码里面我增加了如下log打印

  unsigned int beam_size = ceil((angle_max - angle_min) / angle_increment);LOG_INFO("[lds driver] %s %d: beam_size:%d %f %f %f.", __FUNCTION__, __LINE__,beam_size,angle_max,angle_min,angle_increment);

经过又一次执行崩溃之后,我们终于捕获到了它产生瞬间该函数里面的数据

[ WARN] [1501842255.254595539]: [lds driver] main 276: [lds driver] LD06 poll data timeout.
[ WARN] [1501842256.264604807]: [lds driver] main 276: [lds driver] LD06 poll data timeout.
[ INFO] [1501842257.042441093]: [lds driver] ToLaserscan 228: beam_size:-1 6.283180 0.000000 0.000000.
terminate called after throwing an instance of 'std::bad_alloc'what():  std::bad_alloc

就是上面,我们看到这个时候 angle_increment 为0,但是实际上浮点不一定为0.000,而是后面可能有有一个小数没有表示出来,实际该浮点数可能为 0.000000000000001,而上面log可以看到,在打印beam_size之前,雷达处于无法读取数据的时候,为下电状态。下一瞬间可以读取数据,但是此时angle_increment计算为0.000000,计算angle_increment的电机实际速度应为为极小值,简单说应该是电机没有动作的起来,速度为0,导致计算beam_size转换之后变成一个极大值。

到这里我们就应该明白是如何造成的这个问题了。这个时候怎么修改呢?

bug修复

改bug的方法有很多种,哪一种好,能用就好。 这里我想到的就是把数据使用之前,进行安全检查,转化变量的时候进行static_cast修饰。

增加代码如下:

  /*Calculate the number of scanning points*/if(mSpeed > 0){unsigned int beam_size = static_cast<unsigned int>(ceil((angle_max - angle_min) / angle_increment));...}

显示效果如截图所示:

结语

这就是我使用乐动ld06型号雷达sdk的一些问题解决分享,这里面是一个完整工作解决bug的流程介绍,希望可以给大家一些知识补充。如果大家有更好的想法和需求,也欢迎大家加我好友交流分享哈。


作者:良知犹存,白天努力工作,晚上原创公号号主。公众号内容除了技术还有些人生感悟,一个认真输出内容的职场老司机,也是一个技术之外丰富生活的人,摄影、音乐 and 篮球。关注我,与我一起同行。

                              ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧  END  ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧

推荐阅读

【1】在球场上我向人民币玩家低了头

【2】Linux开发coredump文件分析实战分享

【3】CPU中的程序是怎么运行起来的 必读

【4】cartographer环境建立以及建图测试

【5】设计模式之简单工厂模式、工厂模式、抽象工厂模式的对比

本公众号全部原创干货已整理成一个目录,回复[ 资源 ]即可获得。

乐动ld06激光雷达sdk改bug记录分享相关推荐

  1. 乐行天下激光雷达SDK介绍

    激光雷达SDK简介 乐行天下激光雷达提供完善的SDK接口,可以大大减少进行室内定位,自主导航研究的开发周期. 目前SDK提供windows,linux,android三大系统的运行库. 以及windo ...

  2. 乐动机器人 2D DTOF激光雷达 LD06、LD19驱动包开源仓库分享

    0.官方在知乎公布的产品资料 1. Github平台 Linux SDK: https://github.com/ldrobotSensorTeam/ldlidar_stl_sdk ROS功能包: h ...

  3. WordPress大前端乐动体育指出:主题博客模板新增9个功能,修复7个bug

    5.1版本更新内容: 新增客服系统,支持QQ.微信.手机.自定义链接.评论.回顶部,且可排序可显示在乐动体育(LD26.PRO-基本) 新增自定义社交账号功能以替代现有社交功能(主题设置-社交) 新增 ...

  4. Android Studio 项目设计开发bug记录以及未来新技术

    文章目录 项目设计开发bug记录: (1)打包时出错 (2)关闭项目自启动 (3)显示工具栏 (4)怎么导入jar包 (5)导入工程出现异常 (6)run项目出现异常: (7)修改包名 (8)导入项目 ...

  5. 程序员老在改Bug,就不能一次改好吗?

    作者丨伍杏玲 来源 | 程序人生(ID:coder_life) 程序员的日常三件事:写Bug.改Bug.背锅.连程序员都自我调侃道,为什么每天都在加班?因为我的眼里常含Bug. 但是真的有这么多Bug ...

  6. 名企程序员被裁实录:早上还在改 Bug,晚上就成下岗工

    戳蓝字"CSDN云计算"关注我们哦! 尽管最近新闻铺天盖地的"寒冬说",由于我多年身处在稳定的大公司里,并没有太多的危机感.昨天大伙一起讨论年会表演什么节目,你 ...

  7. 为什么程序员老在改 Bug,就不能一次改好吗?

    程序员的日常三件事:写Bug.改Bug.背锅.连程序员都自我调侃道,为什么每天都在加班?因为我的眼里常含Bug. 但是真的有这么多Bug要改吗?就不能一次改完吗? 程序员听这问题后要拍键盘了,还!真! ...

  8. 乐动手环app下载安装_乐动健康安卓版

    乐动健康安卓版是一款可以随时掌握你身体状况的智能手环,乐动健康安卓版可以直接与乐动健康手环进行连接,查看自己身体的各项指标,掌握自己的身体状况,还可以对个人健康进行管理,个人运动.睡眠.心率.血压等多 ...

  9. Esp8266 进阶之路36【外设篇】乐鑫esp8266芯片SDK编程驱动时间芯片 ds1302,同步网络时间到本地,再也不怕掉电断网也可以同步时间了!(附带Demo)

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1. Esp8266之 搭建开发环境,开始一个"hello ...

  10. 乐鑫esp8266学习rtos3.0笔记:分享在 esp8266 C SDK实现冷暖光色温平滑调节的封装,轻松集成到您的项目去。(附带Demo)

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,不做开发板.仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 基于C SDK的ESP8266开发技术全系列笔记 一.N ...

最新文章

  1. 分享Laravel中blade页面更改没有及时显示在页面的问题解决方案
  2. 2019-1-17王志颖 c语言作业
  3. MapReduce-Reduce端join操作-步骤分析
  4. 文件服务器上传文件的过程,文件服务器上传文件实现过程【分享】
  5. 【codevs1116】四色问题
  6. Spark:性能调优
  7. 多线程3,线程池封装库
  8. 电子元件识别 测量
  9. 取代奶瓶Minidwep-gtk破解WPA 全攻略
  10. Java常用术语解释
  11. 计算机网络考研_概述
  12. imac打开terminal终端器
  13. Cannot enable Hyper-V service
  14. greasemonkey 使用心得
  15. 元宇宙产业委常务副主任委员甘华鸣:狭义元宇宙9大技术:一种基于狭义元宇宙体系结构的观点
  16. 小酌重构系列[10]——分离职责
  17. 计算机人脸识别算哪个专业,人脸识别属于计算机什么领域
  18. 【计算机网络】5层因特网协议栈 概述
  19. 支付宝六(商户会员卡之模板创建)
  20. 【系统分析师之路】第五章 软件工程记忆敲出

热门文章

  1. 程序员的办公好选择:工作效率翻倍,游戏也能超神
  2. 人工智能 感情 自我意识
  3. java 公共方法是什么意思,在java中公共/私有/其他方法的含义是什么意思?
  4. Mac部分按键失灵问题解决
  5. 深入理解G1垃圾收集器
  6. Docker进阶实战
  7. 安卓手机安装magisk
  8. Windows批处理文件bat学习(一)
  9. 如果光猫+hadoop,有化学反应吗?
  10. python实现12306火车票查询