1. 概念:访问了不合法的地址 。通俗一点就是访问了不属于自己的地址。如果这块地址分配给了另一个变量使用,就会破坏别人的数据。从而导致程序运行异常,挂死,输出图像破图等。
2. 踩内存的可能的情形
1)内存访问越界
a)数组访问越界;
b)字符串操作越界;
2)非法指针
a)使用了空指针;
b)使用了释放掉的指针;
c)指针类型转换错误;
3)栈溢出;
4)多线程读写的数据没有加锁保护
5)多线程使用了线程不安全的函数
3. 如何排查
1)删减模块代码,缩小排查范围;
2)加log,打印内存地址/值;
3)将被踩内存设置成只读,在调用栈中查看谁在写;
还有一些结合内核分析的高级手段,待学习
4. 如何避免
写代码时严格遵守编程规范。
1)数组访问边界检查,防止溢出,关于数组大小等关键数值使用宏代替;
2)使用strcpy,strcat,sprintf,strcmp,strcasecmp等字符串操作函数需谨慎,可以以使用strncpy,strlcpy,strncat,strlcat,snprintf,strncmp,strncasecmp等代替防止读写越界;
memcpy在内存重叠时不保证拷贝是正确的,memmove在内存重叠时保证拷贝是正确的;
3)指针释放后及时置空,必要时使用指针非空检查;
4)不要定义过大的局部变量,例如数组,容易造成栈溢出;
5)变量定义好后及时赋初值,特别像结构体这种;
6)代码嵌套适量,防止资源重复申请/释放;
7)多线程时做好线程保护;
踩内存定位的成本很高。一旦写出内存踩踏的代码,排查的成本是按规范写代码的成本的1000x。
注:
在相机系统中,出现系统崩溃或者图像损坏(绿条,粉条,马赛克等)可以检查一下是否有踩内存,但有一种情况就是同一帧的图像出现块状的错位拼接,大片规则粉块,很有可能是由DDR带宽不够,造成某个模块的ddr lantency太大造成的,需要谨慎查找。