记一次调试过程
这是一个在 arm 架构上的 RTOS 上的调试过程。问题现象为使用 thumb 指令集的 libgcc 库的情况下,浮点运算随机出错。经过一番追踪调试,逐步缩小问题范围,最后定位问题,成功解决。
博文持续更新地址,原文作者:LeiCoder
场景
在某款的国产 RTOS 上,由于客户应用需要,使用了thumb 指令集编译的 libgcc 的库,导致了同时运行了 arm 指令集和 thumb 指令集的代码。原本的 RTOS 未设计运行 thumb 指令的代码,也没有严格测试过,所以本次暴露了浮点运算偶尔出错的问题。
测试代码
客户精简过的暴露问题代码如下
unsigned long long ulTa = 0x100;
unsigned long long ulTb = 0x2001;
double dRea, dReb;
double dRes;
while (1) {
= (double)ulTa;
dReb = (double)ulTb;
dRes = dRea / dReb;
if ((dRea == 0.0) || (dReab == 0.0) || (c <= 0.01f)) {
printf("error!!\r\n");
}
}
这段代码的逻辑是强转了两个 unsigned long long 类型,然后进行除法运行,最后判断各个变量的结果是否符合预期,否则就报 error。
问题分析
抓取问题中的关键点:
- 和浮点运算有关,是不是我们的RTOS对于浮点运算的寄存器没有处理好
- 简单的代码反复运行只是偶尔出问题,而不是固定每次出问题,那么考虑其他外部的影响,首先考虑的是中断。
问题调试
bug调试的指导思想是,仔细观察问题剖析问题,提出怀疑一些原因,并修改代码验证。
步骤1 剖析问题
靠近问题的实质,分析问题:既然计算出错,那么看看出错的时候的变量是什么样的。经过一些调试打印发现 3 个 double 类型的变量都出错过。出错的时候,打印这些变量对应地址存储的值,发现这些内存的值有 0 存在。因为 double 变量使用 8 bytes 的空间存放的,这些空间里存放的不是实际值,而是分符号位,指数位等。
根据这个现象,我有理由怀疑是某些时候的强转没有成功。

最低0.47元/天 解锁文章
549





