注意返回类型

首先看一下这两个函数

//从队列中读取数据存入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位整形,问题解决。
总结:
其实编译器已经告警类型不符,但是由于之前的几个告警没有修复,没有注意到这个告警,导致调试浪费时间。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容