如何写Bug - 2 -无效数据长度导致“无限”循环

概述

本文介绍了Bug系列的第2个Bug,讲的是解析报文时,模拟了一个无效的数据长度,触发了C语言函数的隐式规则转换,导致任务进入了超长的循环处理,进而导致运行时错误(Running Time Error)。就如何避免这个问题提出了解决方案,并进行了经验总结。

阅读本文需要了解C语言隐式规则转换的理论基础。

背景

项目需要对基于串口的通信协议进行解析,根据包头确定后续接收数据的长度。后期测试过程中,发现模拟无效数据长度,会导致整个ECU触发运行时错误(Running Time Error ),进而导致程序挂掉。

主体代码

#include <stdio.h>
#include <stdint.h>

#define FRAME_HEAD_SIZE (4U)

uint32_t g_u32_Counter = 0;
uint32_t g_u32_dataLen = 0;

int main()
{
uint32_t index = 0;

//dispatch data length from the protocol, simulate invalid data length 2.(shall be bigger than 4 in normal)
g_u32_dataLen = 2;

for(index = 0; index < g_u32_dataLen - FRAME_HEAD_SIZE; index++)
{
    g_u32_Counter++;
}
printf("expected received data counter is %u\n", g_u32_Counter);

}

运行环境

  • Software: AutoSar OS, CP4.2.2
  • Hardware: S32K146

主要功能

这段代码模拟数据的解析过程,模拟了数据长度为2的报文,但是由于包头固定大小已经是4,会导致index < -2 这种不可思议的判断条件。

那么这种情况下,g_u32_Counter的值会是多少呢?
相信不少人会觉得条件不满足,不会进入循环,值为0。

但是,实际情况是,g_u32_Counter = 4294967294 (0xFF FF FF FE)。

为什么呢?

因为这里发生了C语言的隐式规则转换。粗浅的解释是,在进行同等长度的无符号和有符号的数据计算时,会将有符号数据先转换为无符号数据,然后进行计算。

更深层次的原因是,-2是个负数,在计算机里面是以补码的形式存在,即0xFF FF FF FE, 因而,整个循环次数非常大,触发了Autosar的运行时错误。

该情况很容发生在非法的网络攻击上,需要设计鲁邦的程序,至少坚持到程序被攻克前,保证程序的正常运行。(当然你想通过这种方式来保护程序不受侵害也算是脑洞大开)。

如何避免这个问题

其实只需要做好关键的数据长度检查,无效数据长度进行过滤,并且在设计程序时对关键等价类或者边界充分考虑。

总结

该问题给我们也有一起启发,很多时候,开发更多考虑的是正向,保证基本的功能,而好的测试更多像精密的勘测仪器,帮助我们发现软件中的缺陷,保证整体软件功能和非功能有效性。

测试开发独立

流程上,尽量保证开发和测试独立性,避免既是运动员又是裁判。

测试驱动开发

作为开发人员,应该更多地借鉴测试的一些方法进行编程,比如等价类,边界值等等,保证整体软件质量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xu_Xiangfeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值