天天看点

由于同事设计的代码发现了一些严重的BUG,迟迟得不到解决,影响了整个开发项目的结案。于是,我找他们要来了全部代码,搭建开

作者:物联网全栈开发

由于同事设计的代码发现了一些严重的BUG,迟迟得不到解决,影响了整个开发项目的结案。

于是,我找他们要来了全部代码,搭建开发环境,亲自帮他们分析并解决问题。

在解决了因为多个不同优先级中断相互打断以及IAR代码优化而导致了UART发送状态机状态死锁的BUG之后,我又发现了他们代码中的内存越界访问的问题。

在用JLINK调试代码时,程序以极低的概率运行到死循环。

从call stack看到,进入死循环之前调用的函数为_iar_dlfree_21,据此判断应该是内存的动态分配和释放出现了问题。

从IAR的安装目录下找到了dlmalloc.c文件,把它加入到IAR工程中,这样就可以在free()函数中设置段点,单位运行程序,以详细查看变量状态以及代码行为。

通过malloc函数分配一段内存,除了可以使用的内存区域之外,还包括了4个字节的prev_foot变量,记录上一个内存块的大小,4个字节的head变量,记录当前内存块的大小,以及两个标志位bit0、bit1,bit0表示上一个内存块是否被使用,记为pinuse,bit1表示当前内存块是否有使用,记为cinuse。

当内存块未被使用时,数据区的内容为上一个内存块以及下一个内存块的地址,分别占用4个字节。

在free函数的USAGE_ERROR_ACTION处设置状态,当出现错误时,函数跳转到此处,调入abort函数进入死循环。

分析发现,出现错误时,还在使用的程序块的head被破坏,长度错误而且bit1的使用标志被清零,从而free函数在对释放的内存块合并时,判断数据区的上一个内存块地址错误,即ok_address(fm, F)为假,从而报错。

应该是在通过malloc申请内存之后,对申请到的空间访问超出范围,改写了下一个内存块的head变量。

紧接着我定义了一个环形数组,记录下通过malloc分配的变量标号以及大小。

当发生错误时,从环形数组中找到使用与错误的内存块相邻的上一个内存块的变量,从代码中分析该变量的使用情况,发现在memcpy时长度超过了申请的内存大小,改变了出错内存块的head值。

由于同事设计的代码发现了一些严重的BUG,迟迟得不到解决,影响了整个开发项目的结案。于是,我找他们要来了全部代码,搭建开
由于同事设计的代码发现了一些严重的BUG,迟迟得不到解决,影响了整个开发项目的结案。于是,我找他们要来了全部代码,搭建开
由于同事设计的代码发现了一些严重的BUG,迟迟得不到解决,影响了整个开发项目的结案。于是,我找他们要来了全部代码,搭建开

继续阅读