关于单片机内存溢出的查找方法
2016-05-15 23:31
274 查看
我所知道的内存溢出分为两种,一种是数组溢出,一种是堆栈溢出。
一种内存溢出的定位方法:一般内存溢出多为数组,先查找到内存溢出的变量,然后查看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);
/********************************
4000
*
This is your Code。
************************************/
while(*(uint8*)0X0a45<10000);
return ;
}
如果都到这了,还没有找到溢出的语句,可以猜测是栈溢出,试试将栈放大,然后看看效果,关于栈溢出,请看我的另一篇博文,这里就不做过多的解释了。
写于2016年5月11日深圳
一种内存溢出的定位方法:一般内存溢出多为数组,先查找到内存溢出的变量,然后查看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);
/********************************
4000
*
This is your Code。
************************************/
while(*(uint8*)0X0a45<10000);
return ;
}
如果都到这了,还没有找到溢出的语句,可以猜测是栈溢出,试试将栈放大,然后看看效果,关于栈溢出,请看我的另一篇博文,这里就不做过多的解释了。
写于2016年5月11日深圳
相关文章推荐
- Service的生命周期
- Linux命令行下安装Maven与配置
- BZOJ 4195 程序自动分析
- BZOJ 4195 程序自动分析
- Android线程优先级
- CacheManager运行原理流程图和源码详解
- iOS发开蛋疼集锦
- 总结同学们第十周作业出现的问题
- Mac上的抓包工具Charles[转载]
- 花有重开日——《大象的困局——互联网+时代的传统企业转型难题》
- 注册广播有几种方式,这些方式有何优缺点?请谈谈Android引入广播机制的用意。
- android学习之路-了解android生命周期
- JS学习12(事件)
- c++的强制类型转换
- priority queue 优化的 dijkstra 算法
- beagleBone black 中QT的移植
- 对this的理解又提升了一个阶段
- Genymotion在Mac下的安装设置调试等一些列问题解决
- CDOJ 1351(树形DP)
- 请解释下在单线程模型中Message、Handler、MessageQueue、Looper之间的关系。