乐动ld06激光雷达sdk改bug记录分享
前言:
工作中,有使用过乐动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 ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
推荐阅读
【3】CPU中的程序是怎么运行起来的 必读
本公众号全部原创干货已整理成一个目录,回复[ 资源 ]即可获得。
乐动ld06激光雷达sdk改bug记录分享的更多相关文章
- CDH:5.14.0 中 Hive BUG记录
CDH5.14.0使用的HIVE版本: 自建表log: +----------------------------------------------------+--+ | createtab_st ...
- 微信小程序bug记录与解决
微信小程序bug记录 textarea textarea在模拟器上没有padding,可是在真机上会自带padding,而且在外部改不了,并且在安卓和IOS上padding还不一样 第一张图是在开发工 ...
- 为什么程序员老在改 Bug,就不能一次改好吗?
程序员的日常三件事:写Bug.改Bug.背锅.连程序员都自我调侃道,为什么每天都在加班?因为我的眼里常含Bug. 但是真的有这么多Bug要改吗?就不能一次改完吗? 程序员听这问题后要拍键盘了,还!真! ...
- 曹工改bug:cpu狂飙,old gc频繁,线程神秘死亡连环案件调查报告
曹工改bug:cpu狂飙,old gc频繁,线程神秘死亡连环案件调查报告 前言 前两天,访问开发环境上一个java服务,发现一直转圈圈,因为我开着fiddler,可以看到的现象是,接口一直没返回:本来 ...
- android软件简约记账app开发day08-时间对话框的书写+改bug,改bug
android软件简约记账app开发day08-时间对话框的书写+改bug,改bug 绘制对话跨页面 在添加记账信息功能中,我提供了用户添加备注添加事件的功能,设计是点击时间会弹出一个时间对话框供用户 ...
- 【bug记录】OS Lab3 踩坑记
OS Lab3 踩坑记 Lab3在之前Lab2的基础上,增加了进程建立.调度和中断异常处理.其中测试包括进程建立以及进程调度部分. 由于是第一次做bug记录,而且是调试完bug后再做的记录,所以导致记 ...
- 改bug的乐趣
一直以来,我都不喜欢改bug,不管是自己的,还是别人的.因为我不相信自己的代码会出现问题,一旦出现问题我就会觉得很难堪,因为我觉得我的代码没什么问题.然后我就不知道该怎么来解决这些问题. 最近这一两次 ...
- PKUSC2019 改题记录
PKUSC2019 改题记录 我真的是个sb... 警告:不一定是对的... D1T1 有一个国家由\(n\)个村庄组成,每个村庄有一个人.对每个\(i\in[1,n-1],\)第\(i\)个村庄到第 ...
- BUG 记录:移位运算与扩展欧几里得算法
BUG 记录:移位运算与扩展欧几里得算法 起因 上个月就开始打算用C++写一个ECC的轮子(为什么?折磨自己呗!),奈何自己水平有点差,拖到现在才算写完底层的大数运算.在实现欧几里得算法的时候,我开始 ...
随机推荐
- Oracle打怪升级之路一【Oracle基础、Oracle查询】
前言 背景:2021年马上结束了,在年尾由于工作原因接触到一个政府单位比较传统型的项目,数据库用的是Oracle.需要做的事情其实很简单,首先从大约2000多张表中将表结构及数据导入一个共享库中,其次 ...
- Spring 处理请求和响应相关的注解
@Controller 默认返回 templates 目录下的 string.html 页面内容. 在方法中加上 @ResponseBody 注解,可以返回JSON.XML或自定义mediaType的 ...
- css 文本基础 实战 小米官方卡片案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 乒乓球队比赛,甲队有abc三人,乙队有xyz三人。 抽签得出比赛名单:a不和x比,c不和x,z比, 利用集合求出比赛名单
import java.util.HashMap; import java.util.Map; /** * 乒乓球队比赛,甲队有abc三人,乙队有xyz三人. * 抽签得出比赛名单:a不和x比,c不和 ...
- 基于Dapper的分布式链路追踪入门——Opencensus+Zipkin+Jaeger
微信搜索公众号 「程序员白泽」,进入白泽的编程知识分享星球 最近做了一些分布式链路追踪有关的东西,写篇文章来梳理一下思路,或许可以帮到想入门的同学.下面我将从原理到demo为大家一一进行讲解,欢迎评论 ...
- Vulnhub系列:Os-hackNos
0x01环境搭建 靶机链接: https://www.vulnhub.com/entry/hacknos-os-hacknos,401/发布日期: 2019.11.27靶机描述: 描述 难度:容易中级 ...
- 解决excel两表之间数据关联关系,知道这几招就够了
用过SAP的凭证批量录入模板(Excel文件)的都知道,一个凭证由[抬头]和多个[行项目]组成,这是一个关于excel两表信息关联的典型场景. 这里头蕴藏着一个麻烦:当我们需要一次性录入多个凭证时,如 ...
- Maven Archetype 多 Module 自定义代码脚手架
大部分公司都会有一个通用的模板项目,帮助你快速创建一个项目.通常,这个项目需要集成一些公司内部的中间件.单元测试.标准的代码格式.通用的代码分层等等. 今天,就利用 Maven 的 Archetype ...
- 《剑指offer》面试题16. 数值的整数次方
问题描述 实现函数double Power(double base, int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 示例 1: 输入: 2.0 ...
- 《剑指offer》面试题29. 顺时针打印矩阵
问题描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4 ...