我所知道的内存溢出分为两种,一种是数组溢出,一种是堆栈溢出。
一种内存溢出的定位方法:一般内存溢出多为数组,先查找到内存溢出的变量,然后查看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日深圳