首先看一下这两个函数
//从队列中读取数据存入pbuff, 返回pulRecvdLen长度
uint8_t recvReadEx(Queue *q, uint8_t *pbuff, uint32_t ulRecvLen, uint32_t *pulRecvdLen);
//发送AT命令, 读取并对比返回值
uint32_t gprs_read_AT(void);
uint8_t recvReadEx(Queue *q, uint8_t *pbuff, uint32_t ulRecvLen, uint32_t *pulRecvdLen)
{
uint8_t ch;
uint32_t i;
ch = 0;
i = 0;
while(readRecvQue(q, &ch, 1) == 1)
{
pbuff[i] = ch;
i++;
if(ulRecvLen != 0)
{
if(i == ulRecvLen)
{
break;
}
}
}
if(i > 0)
{
*pulRecvdLen = i;
return 1;
}
else
{
return 0;
}
}
uint32_t gprs_read_AT(void)
{
uint8_t buff[20];
uint8_t *p = NULL;
uint8_t rl;//read len;
uint8_t res;
res = recvReadEx(pGprsRecvQue, buff, 0, &rl);
p = strstr(buff, "OK");
if(p != NULL)
{
return DR_AT_OK;
}
else
{
return DR_AT_ERR;
}
}
我先描述一下bug现象
gprs_read_AT通过recvReadEx读取队列中的值存入buff[20],但每次执行recvReadEx,在recvReadEx中,buff的内容时正确的,但是在函数返回到gprs_read_AT后buff的内容就会变。
recvReadEx执行时,buff在内存中的数据
Paste_Image.png返回到gprs_read_AT时,buff在内存中的数据
Paste_Image.png肯定是内存中的数据被覆盖了,但是时什么导致的呢。
单步执行,发现在recvReadEx中执行完*pulRecvdLen = i;后数据被覆盖,将问题锁定在这条语句,传入的 rl 地址为0xC0B04993,buff的首地址为0xC0B04994,经过仔细阅读,发现recvReadEx中临时变量 i 为32位整形,而传收入的rl为8位整形,因此pulRecvdLen会覆盖rl后3个字节的数据。
将rl修改为32位整形,问题解决。
总结:
其实编译器已经告警类型不符,但是由于之前的几个告警没有修复,没有注意到这个告警,导致调试浪费时间。
网友评论