关于单片机内存溢出的查找方法

时间:2022-10-27 19:48:09

我所知道的内存溢出分为两种,一种是数组溢出,一种是堆栈溢出。

一种内存溢出的定位方法:一般内存溢出多为数组,先查找到内存溢出的变量,然后查看mp1地址映射文件,按照序列,以溢出的变量为基地址,向上查找,找数组,然后在代码中查到该数组的序列填充,大约查找3至5个数组,如果均没有发现溢出,使用下面的方法。

 

另一种内存溢出的定位方法:类似于pcb板的割线,利用while死循环进行定位,这种方法的大前提是需要知道内存溢出的变量。

       语句如下:

              While(A);

A在这里必须是全局变量,A可以是某一变量,也可以是某一语句,比如A<10。当A条件满足时,程序会在这里死循环。

       while(A);的放置,该语句使用时最好大于2句,放置位置尽可能的囊括多的代码,若果没有大致思路可以试试将函数放置在主程序中,随便放置3个以上的语句。

 

举个栗子:

uint8 B(void)

{

       uint8 ret;

       while(A<10000)

/*********************************

This is your Code。

************************************/

       while(A<10000);

       return ;

}

 

当程序死在第一条语句是,可以认为溢出不是该函数造成的,那么可以去别的地方继续尝试,通常第一次会把两个语句放置的范围大一点,然后一点一点的缩小距离,类似于PCB 中的割板、或者数学中的二分法。

当程序死在第二条语句是,可以暂时猜测是该函数造成的内存溢出,然后根据函数的代码长度,将范围继续缩短,重点放在有数组地址写的地方,该地方溢出的可能性最大。

 

如果查找后发现代码没有问题,可以考虑是否是堆栈过小引起的内存溢出。将堆栈的地址范围放大,再看看是否存在溢出。

 

如果溢出的变量为静态局部变量,可以在mp1文件中找到溢出的变量的绝对地址,然后取该地址的值,进行判断。

 

例:static uint8 A;

       在mp1中A的绝对地址为0x0a45;

A变量的判别条件就变为 *(uint8*)0X0a45<10000;

 

上面的例子就变为

uint8 B(void)

{

       uint8 ret;

       while(*(uint8*)0X0a45<10000);

/*********************************

This is your Code。

************************************/

       while(*(uint8*)0X0a45<10000);

       return ;

}

 

        如果都到这了,还没有找到溢出的语句,可以猜测是栈溢出,试试将栈放大,然后看看效果,关于栈溢出,请看我的另一篇博文,这里就不做过多的解释了。                                                                                                                             

                                                                                                                                                                               写于2016年5月11日深圳